2009-10-04 2 views
15

Ich muss eine Python-Liste mit mehreren Attributen sortieren. Ich kann in aufsteigender Reihenfolge tun, die für alle leicht Attribute mitPython: Liste Sortierung mit mehreren Attributen und gemischte Reihenfolge

L.sort(key=operator.attrgetter(attribute)).... 

aber das Problem ist, dass ich habe gemischte Konfigurationen für Aufstiegs-/Abstiegs ... Ich habe zu „imitieren“ ein bisschen die SQL-Order By wo Sie können etwas wie "Name ASC, Jahr DESC" tun. Gibt es eine Möglichkeit, dies einfach in Python zu tun, ohne eine benutzerdefinierte Vergleichsfunktion implementieren zu müssen?

+3

@ecatmur Diese Frage ist älter als die andere. Das Duplikat ist umgekehrt. – Jesse

Antwort

26

Wenn Ihre Attribute numerisch sind, können Sie dies haben.

def mixed_order(a): 
    return (a.attribute1, -a.attribute2) 

someList.sort(key=mixed_order) 

Wenn Ihre Attribute Zeichenfolgen oder andere komplexere Objekte enthalten, haben Sie einige Möglichkeiten. Die Methode .sort() ist stabil: Sie können mehrere Durchgänge ausführen. Dies ist vielleicht der einfachste. Es ist auch bemerkenswert schnell.

def key1(a): return a.attribute1 
def key2(a): return a.attribute2 

someList.sort(key=key2, reverse=True) 
someList.sort(key=key1) 

Wenn dies die einzige Art ist, können Sie Ihre eigenen speziellen Vergleichsoperatoren definieren. Minimal benötigen Sie __eq__ und __lt__. Die anderen vier können aus diesen beiden durch einfache Logik abgeleitet werden.

+0

danke! callint sort() hat sich mehrfach als perfekte Lösung für mich herausgestellt! –

+0

Danke für Ihre Antwort! Nur ein bisschen Verwirrung bezüglich des ersten Teils; Führt die Rückgabe eines Tupels eine komplexe Sortierung mit höheren Indexwerten mit niedrigerer Priorität durch? Ich denke, meine Frage ist allgemeiner: Wie verhält sich 'cmp', wenn zwei Tupel ausgegeben werden? Ich schaute mich um und kann das nicht dokumentiert finden. –

+0

__eq__ kann mit einfacher Logik aus __lt__ abgeleitet werden. :) – Tony

5

Sie können nicht, aber das Schreiben der Funktion vergleichen, ist einfach:

def my_cmp(a, b): 
    return cmp(a.foo, b.foo) or cmp(b.bar, a.bar) 
L.sort(my_cmp) 
7

Eine benutzerdefinierte Funktion, um Ihren Code besser lesbar machen wird. Wenn Sie viele Sortiervorgänge haben und Sie nicht wollen, obwohl diese Funktionen erstellen, können Sie LAMBDA verwenden:

L.sort(lambda x, y: cmp(x.name, y.name) or -cmp(x.year, y.year))