Oder wie kann ich eine Liste von Wörterbüchern praktisch nach mehreren Schlüsseln sortieren?
Ich habe eine Liste von Diktaten:
b = [{u'TOT_PTS_Misc': u'Utley, Alex', u'Total_Points': 96.0},
{u'TOT_PTS_Misc': u'Russo, Brandon', u'Total_Points': 96.0},
{u'TOT_PTS_Misc': u'Chappell, Justin', u'Total_Points': 96.0},
{u'TOT_PTS_Misc': u'Foster, Toney', u'Total_Points': 80.0},
{u'TOT_PTS_Misc': u'Lawson, Roman', u'Total_Points': 80.0},
{u'TOT_PTS_Misc': u'Lempke, Sam', u'Total_Points': 80.0},
{u'TOT_PTS_Misc': u'Gnezda, Alex', u'Total_Points': 78.0},
{u'TOT_PTS_Misc': u'Kirks, Damien', u'Total_Points': 78.0},
{u'TOT_PTS_Misc': u'Worden, Tom', u'Total_Points': 78.0},
{u'TOT_PTS_Misc': u'Korecz, Mike', u'Total_Points': 78.0},
{u'TOT_PTS_Misc': u'Swartz, Brian', u'Total_Points': 66.0},
{u'TOT_PTS_Misc': u'Burgess, Randy', u'Total_Points': 66.0},
{u'TOT_PTS_Misc': u'Smugala, Ryan', u'Total_Points': 66.0},
{u'TOT_PTS_Misc': u'Harmon, Gary', u'Total_Points': 66.0},
{u'TOT_PTS_Misc': u'Blasinsky, Scott', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Carter III, Laymon', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Coleman, Johnathan', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Venditti, Nick', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Blackwell, Devon', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Kovach, Alex', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Bolden, Antonio', u'Total_Points': 60.0},
{u'TOT_PTS_Misc': u'Smith, Ryan', u'Total_Points': 60.0}]
und ich muss eine Mehrschlüsselsortierung verwenden, die von Total_Points umgekehrt und dann nicht von umgekehrt wird TOT_PTS_Misc
.
Dies kann an der Eingabeaufforderung wie folgt erfolgen:
a = sorted(b, key=lambda d: (-d['Total_Points'], d['TOT_PTS_Misc']))
Aber ich muss dies durch eine Funktion ausführen, bei der ich die Liste und die Sortiertasten übergebe. Zum Beispiel def multikeysort(dict_list, sortkeys):
.
Wie kann die Lambda-Zeile verwendet werden, die die Liste für eine beliebige Anzahl von Schlüsseln sortiert, die an die Multikeysort-Funktion übergeben werden, und berücksichtigt werden, dass die Sortierschlüssel eine beliebige Anzahl von Schlüsseln haben können und diejenigen, die umgekehrte Sortierungen benötigen, identifiziert werden mit einem '-' davor?
cmp()
ist für Python3 nicht verfügbar, daher musste ich es selbst definieren, wie hier erwähnt: stackoverflow.com/a/22490617/398514cmp
Schlüsselwort entfernt, aber diecmp()
Funktion wird noch 4 Zeilen weiter oben verwendet. Ich habe es mit 3.2, 3.3, 3.4 und 3.5 versucht, alle sind beim Funktionsaufruf fehlgeschlagen, weilcmp()
nicht definiert. Der dritte Punkt hier ( docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons ) erwähnt die Behandlungcmp()
als weg.Dieser Beitrag enthält einen guten Überblick über verschiedene Techniken, um dies zu tun. Wenn Ihre Anforderungen einfacher sind als "Full Bidirectional Multikey", werfen Sie einen Blick darauf. Es ist klar, dass die akzeptierte Antwort und der Blog-Beitrag, auf den ich gerade verwiesen habe, sich gegenseitig beeinflusst haben, obwohl ich nicht weiß, in welcher Reihenfolge.
Für den Fall, dass der Link stirbt, finden Sie hier eine sehr kurze Zusammenfassung der Beispiele, die oben nicht behandelt wurden:
quelle
result = cmp(fn(left), fn(right))
Ich weiß, dass dies eine ziemlich alte Frage ist, aber keine der Antworten erwähnt, dass Python eine stabile Sortierreihenfolge für seine Sortierroutinen wie
list.sort()
und garantiertsorted()
, was bedeutet, dass Elemente, die gleich sind, ihre ursprüngliche Reihenfolge beibehalten.Dies bedeutet, dass das Äquivalent von
ORDER BY name ASC, age DESC
(unter Verwendung der SQL-Notation) für eine Liste von Wörterbüchern wie folgt ausgeführt werden kann:Beachten Sie, wie die Elemente zuerst nach dem Attribut "kleiner"
age
(absteigend) und dann nach dem Attribut "groß" sortiert werdenname
, was zur korrekten endgültigen Reihenfolge führt.Das Umkehren / Invertieren funktioniert für alle bestellbaren Typen, nicht nur für Zahlen, die Sie durch Setzen eines Minuszeichens negieren können.
Und aufgrund des in (zumindest) CPython verwendeten Timsort-Algorithmus ist dies in der Praxis eigentlich ziemlich schnell.
quelle
quelle
some_string.split(",")
Ich verwende das Folgende zum Sortieren eines 2D-Arrays nach mehreren Spalten
Dies könnte erweitert werden, um an einer beliebigen Anzahl von Elementen zu arbeiten. Ich denke eher, dass es besser ist, ein besseres Zugriffsmuster auf Ihre sortierbaren Schlüssel zu finden, als einen ausgefallenen Komparator zu schreiben.
quelle
Ich hatte heute ein ähnliches Problem - ich musste Wörterbuchelemente nach absteigenden numerischen Werten und nach aufsteigenden Zeichenfolgenwerten sortieren. Um das Problem widersprüchlicher Richtungen zu lösen, habe ich die ganzzahligen Werte negiert.
Hier ist eine Variante meiner Lösung - wie für OP
Sehr einfach - und wirkt wie ein Zauber
quelle
Demonstration:
Das Parsen ist etwas fragil, lässt aber zumindest eine variable Anzahl von Leerzeichen zwischen den Schlüsseln zu.
quelle
Da Sie bereits mit Lambda vertraut sind, finden Sie hier eine weniger ausführliche Lösung.
quelle