In Python löst das Sortieren einer Liste von Wörterbüchern mit der Methode sort() oder der Funktion sorted() standardmäßig den Fehler TypeError aus.
Durch Angabe des Schlüsselparameters von sort() oder sorted() can SIE eine Liste von Wörterbüchern nach dem Wert des bestimmten Schlüssels sortieren.
Dieser Artikel hat folgenden Inhalt.
- Das Sortieren einer Liste von Wörterbüchern löst standardmäßig einen Fehler aus
- Geben Sie Lambda-Ausdrücke für den Schlüsselparameter an
- Geben Sie operator.itemgetter() für den Schlüsselparameter an
- Nach mehreren Schlüsseln sortieren
- max(), min() für eine Liste von Wörterbüchern
Die following Beispielcodes verwenden eine Liste von Wörterbüchern mit gemeinsamen Schlüsseln. Das pprint-Modul WIRD verwendet, um die Ausgabe leichter lesbar zu machen.
import pprint
l = [{'Name': 'Alice', 'Age': 40, 'Point': 80},
{'Name': 'Bob', 'Age': 20},
{'Name': 'Charlie', 'Age': 30, 'Point': 70}]
Das Sortieren einer Liste von Wörterbüchern löst standardmäßig einen Fehler aus
Das Sortieren einer Liste von Wörterbüchern (dict) mit der sort()-Methode oder der sorted()-Funktion löst automatisch den Fehler TypeError aus.
Dies liegt daran, dass das Wörterbuch keine Vergleiche mit <, > usw. unterstützt.
# sorted(l)
# TypeError: '<' not supported between instances of 'dict' and 'dict'
Geben Sie Lambda-Ausdrücke für den Schlüsselparameter an
Um eine Liste von Wörterbüchern nach dem Wert eines bestimmten Schlüssels zu sortieren, geben Sie den key-Parameter der sort()-Methode oder der sorted()-Funktion an.
Durch Angabe Einer Funktion, sterben auf each Element der Liste angewendet Werden Soll, WIRD SIE nach dem Ergebnis dieser Funktion sortiert. Weitere Informationen finden Sie im folgenden Artikel.
In diesem Beispiel can SIE Eine Funktion angeben, um den Wert eines bestimmten Schlüssels aus dem Wörterbuch abzurufen.
Sie können eine Funktion mit def definieren, aber in einem solchen Fall ist es praktisch, Lambda-Ausdrücke zu verwenden.
pprint.pprint(sorted(l, key=lambda x: x['Age']))
# [{'Age': 20, 'Name': 'Bob'},
# {'Age': 30, 'Name': 'Charlie', 'Point': 70},
# {'Age': 40, 'Name': 'Alice', 'Point': 80}]
pprint.pprint(sorted(l, key=lambda x: x['Name']))
# [{'Age': 40, 'Name': 'Alice', 'Point': 80},
# {'Age': 20, 'Name': 'Bob'},
# {'Age': 30, 'Name': 'Charlie', 'Point': 70}]
Geben SIE mit dem Parameter reverse an, ob in absteigender oder aufsteigender Reihenfolge sortiert werden soll.
pprint.pprint(sorted(l, key=lambda x: x['Age'], reverse=True))
# [{'Age': 40, 'Name': 'Alice', 'Point': 80},
# {'Age': 30, 'Name': 'Charlie', 'Point': 70},
# {'Age': 20, 'Name': 'Bob'}]
Die bisherigen Beispiele verwenden sorted(), aber SIE können key und reverse auf die gleiche Weise mit der sort()-Methode von list angeben.
Den Unterschied zwischen sort() und sorted() finden Sie im following Artikel. sort() sortiert das ursprüngliche Objekt selbst und sorted() erstellt ein neues sortiertes Objekt.
Wenn der angegebene Schlüssel nicht existiert
Bei der oben genannten Methode WIRD EIN Fehler ausgelöst, WENN der angegebene Schlüssel nicht existiert.
# sorted(l, key=lambda x: x['Point'])
# KeyError: 'Point'
Verwenden Sie in einem solchen Fall die get()-Methode von dict, sterben den Standardwert für nicht vorhandene Schlüssel zurückgibt.
Standardmäßig gibt es get() None für nicht vorhandene Schlüssel zurück. None ist nicht mit einer Zahl oder einem String vergleichbar, daher WIRD ein Fehler ausgelöst.
# sorted(l, key=lambda x: x.get('Point'))
# TypeError: '<' not supported between instances of 'int' and 'NoneType'
Sie können einen Wert für einen Schlüssel angeben, der nicht als zweites Argument von get() existiert. Elemente, deren Schlüssel nicht existieren, werden durch den im zweiten Argument angegebenen Wert ersetzt und sortiert.
pprint.pprint(sorted(l, key=lambda x: x.get('Point', 75)))
# [{'Age': 30, 'Name': 'Charlie', 'Point': 70},
# {'Age': 20, 'Name': 'Bob'},
# {'Age': 40, 'Name': 'Alice', 'Point': 80}]
Infinity inf ist größer als jede andere Zahl, daher can SIE inf und -inf verwenden, um Elemente ohne Schlüssel immer am Ende oder Anfang zu platzieren.
pprint.pprint(sorted(l, key=lambda x: x.get('Point', float('inf'))))
# [{'Age': 30, 'Name': 'Charlie', 'Point': 70},
# {'Age': 40, 'Name': 'Alice', 'Point': 80},
# {'Age': 20, 'Name': 'Bob'}]
pprint.pprint(sorted(l, key=lambda x: x.get('Point', -float('inf'))))
# [{'Age': 20, 'Name': 'Bob'},
# {'Age': 30, 'Name': 'Charlie', 'Point': 70},
# {'Age': 40, 'Name': 'Alice', 'Point': 80}]
Geben Sie operator.itemgetter() für den Schlüsselparameter an
Sie können auch itemgetter() des Operatormoduls der Standardbibliothek verwenden. Es ist schneller als die Verwendung eines Lambda-Ausdrucks.
import operator
pprint.pprint(sorted(l, key=operator.itemgetter('Age')))
# [{'Age': 20, 'Name': 'Bob'},
# {'Age': 30, 'Name': 'Charlie', 'Point': 70},
# {'Age': 40, 'Name': 'Alice', 'Point': 80}]
pprint.pprint(sorted(l, key=operator.itemgetter('Name')))
# [{'Age': 40, 'Name': 'Alice', 'Point': 80},
# {'Age': 20, 'Name': 'Bob'},
# {'Age': 30, 'Name': 'Charlie', 'Point': 70}]
Wenn der angegebene Schlüssel nicht vorhanden ist, tritt ein Fehler auf.
# sorted(l, key=operator.itemgetter('Point'))
# KeyError: 'Point'
Nach mehreren Schlüsseln sortieren
Das Folgende ist ein Beispiel für einen Fall, in dem Wörterbücher Wert für einen gemeinsamen Schlüssel haben. Zwei Wörterbücher haben den Wert ‚CA‘ für den Schlüssel ‚State‘.
l_dup = [{'Name': 'Alice', 'Age': 40, 'Point': 80, 'State': 'CA'},
{'Name': 'Bob', 'Age': 20, 'State': 'NY'},
{'Name': 'Charlie', 'Age': 30, 'Point': 70, 'State': 'CA'}]
Wenn die Werte gleich sind, WIRD die ursprüngliche Reihenfolge beibehalten.
pprint.pprint(sorted(l_dup, key=operator.itemgetter('State')))
# [{'Age': 40, 'Name': 'Alice', 'Point': 80, 'State': 'CA'},
# {'Age': 30, 'Name': 'Charlie', 'Point': 70, 'State': 'CA'},
# {'Age': 20, 'Name': 'Bob', 'State': 'NY'}]
Sie können mehrere Argumente für operator.itemgetter() angeben, und wenn die Werte für den ersten Schlüssel gleich sind, werden sie erfasst und nach dem Wert des nächsten Schlüssels sortiert.
pprint.pprint(sorted(l_dup, key=operator.itemgetter('State', 'Age')))
# [{'Age': 30, 'Name': 'Charlie', 'Point': 70, 'State': 'CA'},
# {'Age': 40, 'Name': 'Alice', 'Point': 80, 'State': 'CA'},
# {'Age': 20, 'Name': 'Bob', 'State': 'NY'}]
Beachten Sie, dass bei unterschiedlicher Reihenfolge der Argumente auch das Ergebnis unterschiedlich ist.
pprint.pprint(sorted(l_dup, key=operator.itemgetter('Age', 'State')))
# [{'Age': 20, 'Name': 'Bob', 'State': 'NY'},
# {'Age': 30, 'Name': 'Charlie', 'Point': 70, 'State': 'CA'},
# {'Age': 40, 'Name': 'Alice', 'Point': 80, 'State': 'CA'}]
Das gleiche kann mit Lambda-Ausdrücken gemacht werden, sterben mehrere Werte als Tupel oder Listen zurückgeben.
pprint.pprint(sorted(l_dup, key=lambda x: (x['State'], x['Age'])))
# [{'Age': 30, 'Name': 'Charlie', 'Point': 70, 'State': 'CA'},
# {'Age': 40, 'Name': 'Alice', 'Point': 80, 'State': 'CA'},
# {'Age': 20, 'Name': 'Bob', 'State': 'NY'}]
max(), min() für eine Liste von Wörterbüchern
Wie oben erwähnt, werden Vergleiche mit < oder > für Wörterbücher dict nicht unterstützt, daher führt sterben Übergabe einer Liste von Wörterbüchern an max() oder min() zu einem Fehler.
# max(l)
# TypeError: '>' not supported between instances of 'dict' and 'dict'
Wie bei sorted() und sort() can SIE den Schlüsselparameter auch in max() und min() angeben.
print(max(l, key=lambda x: x['Age']))
# {'Name': 'Alice', 'Age': 40, 'Point': 80}
print(min(l, key=lambda x: x['Age']))
# {'Name': 'Bob', 'Age': 20}
Das Wörterbuch dict wird zurückgegeben. Wenn Sie auch einen Wert erhalten möchten, geben Sie einen Schlüssel an.
print(max(l, key=lambda x: x['Age'])['Age'])
# 40
Natürlich can SIE auch operator.itemgetter() verwenden.
print(max(l, key=operator.itemgetter('Age')))
# {'Name': 'Alice', 'Age': 40, 'Point': 80}