Sorting on multiple values, some ascending, some descending
Christophe
chris.cavalaria at free.fr
Thu Jan 4 05:21:27 EST 2007
bearophileHUGS at lycos.com a écrit :
> Raymond Hettinger:
>> The simplest way is to take advantage of sort-stability and do
>> successive sorts. For example, to sort by a primary key ascending and
>> a secondary key decending:
>> L.sort(key=lambda r: r.secondary, reverse=True)
>> L.sort(key=lambda r: r.primary)
>
> That's probably the faster and simpler way.
> The following solution is probably slow, memory-hungry, and it's not
> tested much so it may be buggy too, but it shows my idea, and bugs can
> be fixed:
>
> class Inverter:
> def __init__(self, item, reversed=False):
> self.item = item
> self.reversed = reversed
> def __cmp__(self, other):
> if self.reversed:
> return cmp(other.item, self.item)
> else:
> return cmp(self.item, other.item)
>
> data = [[1, "a", "b"], [1, "b", "d"], [1, "d", "a"]]
> reverses = [True, False, False]
>
> print sorted(data, key=lambda subseq: map(Inverter, subseq, reverses))
Nice trick, but don't get too caught up using classes ;) Try that one
instead for much better performance :
class Inverter:
def __init__(self, item):
self.item = item
def __cmp__(self, other):
return cmp(other, self.item)
def invert_if(item, reversed=False):
if reversed:
return Inverter(item)
return item
data = [[1, "a", "b"], [1, "b", "d"], [1, "d", "a"]]
reverses = [True, False, False]
print sorted(data, key=lambda subseq: map(invert_, subseq, reverses))
More information about the Python-list
mailing list