Ich habe eine Liste von Listen:
[[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]
Wenn ich nach einem Element sortieren wollte, sagen wir das große / kurze Element, könnte ich es über tun s = sorted(s, key = itemgetter(1))
.
Wenn ich sowohl nach groß / klein als auch nach Farbe sortieren wollte , könnte ich die Sortierung zweimal durchführen, einmal für jedes Element, aber gibt es einen schnelleren Weg?
sort
. Das heißt ,sorted([(4, 2), (0, 3), (0, 1)]) == [(0, 1), (0, 3), (4, 2)]
.Antworten:
Ein Schlüssel kann eine Funktion sein, die ein Tupel zurückgibt:
Oder Sie können dasselbe erreichen
itemgetter
(was schneller ist und einen Python-Funktionsaufruf vermeidet):Und beachten Sie, dass Sie hier verwenden können,
sort
anstatt zu verwendensorted
und dann neu zuzuweisen:quelle
-
von Ganzzahlen)revrse=True
nur bewerben möchtex[1]
? Ist das möglich?s = sorted(s, key = operator.itemgetter(2))
dann nach dem primären.s = sorted(s, key = operator.itemgetter(1), reverse=True)
Nicht ideal, funktioniert aber.-1
.Ich bin mir nicht sicher, ob dies die pythonischste Methode ist ... Ich hatte eine Liste von Tupeln, die zuerst nach absteigenden Ganzzahlwerten und zweitens alphabetisch sortiert werden mussten. Dies erforderte die Umkehrung der ganzzahligen Sortierung, jedoch nicht der alphabetischen Sortierung. Hier war meine Lösung: (Im laufenden Betrieb in einer Prüfung war mir übrigens nicht einmal bewusst, dass Sie sortierte Funktionen "verschachteln" können)
quelle
b = sorted(a, key = lambda x: (-x[1], x[0]))
, als wäre es besser, welche Kriterien zuerst gelten. Was die Effizienz angeht, bin ich mir nicht sicher, ob jemand Zeit hat.Es scheint, Sie könnten a
list
anstelle von a verwendentuple
. Dies wird meiner Meinung nach wichtiger, wenn Sie Attribute anstelle von 'magischen Indizes' einer Liste / eines Tupels abrufen.In meinem Fall wollte ich nach mehreren Attributen einer Klasse sortieren, wobei die eingehenden Schlüssel Zeichenfolgen waren. Ich brauchte unterschiedliche Sortierungen an verschiedenen Orten und wollte eine gemeinsame Standardsortierung für die übergeordnete Klasse, mit der Clients interagierten. Ich musste die 'Sortierschlüssel' nur überschreiben, wenn ich es wirklich 'brauchte', aber auch so, dass ich sie als Listen speichern konnte, die die Klasse gemeinsam nutzen konnte
Also habe ich zuerst eine Hilfsmethode definiert
dann, um es zu benutzen
Dies verwendet die generierte Lambda-Funktion, sortiert die Liste nach
object.attrA
und nimmt dann an,object.attrB
dassobject
ein Getter vorhanden ist, der den angegebenen Zeichenfolgennamen entspricht. Und der zweite Fall würde bisobject.attrC
dahin sortierenobject.attrA
.Auf diese Weise können Sie auch potenzielle Sortieroptionen nach außen offenlegen, die von einem Verbraucher gleichermaßen geteilt werden können, einen Komponententest durchführen oder Ihnen möglicherweise mitteilen, wie die Sortierung für einen Vorgang in Ihrer API erfolgen soll, indem Sie nur eine Liste angeben müssen und nicht Koppeln Sie sie mit Ihrer Back-End-Implementierung.
quelle
Einige Jahre zu spät zur Party, aber ich möchte sowohl nach 2 Kriterien sortieren als auch verwenden
reverse=True
. Falls jemand anderes wissen möchte, wie, können Sie Ihre Kriterien (Funktionen) in Klammern setzen:quelle
Hier ist eine Möglichkeit: Sie schreiben Ihre Sortierfunktion im Grunde neu, um eine Liste von Sortierfunktionen zu erstellen. Jede Sortierfunktion vergleicht die Attribute, die Sie testen möchten. Bei jedem Sortiertest prüfen Sie, ob die cmp-Funktion eine Rückgabe ungleich Null zurückgibt Wenn ja, brechen Sie und senden Sie den Rückgabewert. Sie nennen es, indem Sie ein Lambda einer Funktion einer Liste von Lambdas aufrufen.
Sein Vorteil ist, dass es die Daten einmalig durchläuft und nicht wie andere Methoden. Eine andere Sache ist, dass es an Ort und Stelle sortiert, während sortiert eine Kopie zu machen scheint.
Ich habe es verwendet, um eine Rangfunktion zu schreiben, die eine Liste von Klassen ordnet, in denen sich jedes Objekt in einer Gruppe befindet und eine Bewertungsfunktion hat, aber Sie können eine beliebige Liste von Attributen hinzufügen. Beachten Sie die un-Lambda-ähnliche, wenn auch hackige Verwendung eines Lambda, um einen Setter zu nennen. Der Rangteil funktioniert nicht für eine Reihe von Listen, die Sortierung jedoch.
Hier ist eine Möglichkeit, eine Liste von Objekten zu ordnen
quelle