Ordering python sets

Peter Otten __peter__ at web.de
Mon Oct 27 18:27:30 CET 2008

```bearophileHUGS at lycos.com wrote:

> Glenn Linderman:
>
>> how does one create a key that corresponds to ascending integer followed
>> by descending character string?
>
> slow.)
>
>>>> seq = [(10, "abb"), (5, "zul"), (5, "hal"), (2, "of")]
>>>> sorted(seq, key=lambda (n,s): (-n, s), reverse=True)
> [(2, 'of'), (5, 'zul'), (5, 'hal'), (10, 'abb')]
>
> A little harder question is how to create a key that corresponds to
> ascending string followed by descending string?
>
> To do that you can sort the data two times, relying on the stable
> nature of the Python sort.
>
> Another (silly?) solution may be to invent a "negate" function for
> strings too:
>
>>>> strneg = lambda txt: txt.translate(itable)
>>>> itable = "".join(chr(i) for i in xrange(255, -1, -1))
>>>> pairs = [('al', 'boo'), ('zul', 'ao'), ('al', 'den'), ('zul', 'o')]
>>>> sorted(pairs, key=lambda (s1,s2): (s1, strneg(s2)))
> [('al', 'den'), ('al', 'boo'), ('zul', 'o'), ('zul', 'ao')]

Here's a class that can negate arbitrary values:

>>> class Neg(object):
...     def __init__(self, value):
...             self.value = value
...     def __cmp__(self, other):
...             return -cmp(self.value, other.value)
...
>>> pairs = [('al', 'boo'), ('zul', 'ao'), ('al', 'den'), ('zul', 'o')]
>>> sorted(pairs, key=lambda (s, t): (s, Neg(t)))
[('al', 'den'), ('al', 'boo'), ('zul', 'o'), ('zul', 'ao')]

```