Python 3 sortiert ein Diktat nach seinen Werten

78

Die einzigen Methoden, die ich gefunden habe, funktionieren für Python2 oder geben nur eine Liste von Tupeln zurück.

Ist es möglich, das Wörterbuch beispielsweise {"aa": 3, "bb": 4, "cc": 2, "dd": 1}nach seinen Werten zu sortieren ?

Die Reihenfolge des sortierten Wörterbuchs, das ich erreichen möchte, ist vom größten zum kleinsten. Ich möchte, dass die Ergebnisse so aussehen:

bb 4
aa 3
cc 2
dd 1

Und nach dem Sortieren möchte ich es in einer Textdatei speichern.

Salvatore Cosentino
quelle

Antworten:

119

itemgetter(siehe andere Antworten) ist (wie ich weiß) effizienter für große Wörterbücher, aber für den allgemeinen Fall glaube ich, dass dies d.getgewinnt. Und es erfordert kein Extra import.

>>> d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
>>> for k in sorted(d, key=d.get, reverse=True):
...     k, d[k]
...
('bb', 4)
('aa', 3)
('cc', 2)
('dd', 1)

Beachten Sie, dass alternativ können Sie einstellen , d.__getitem__wie keyFunktion , die über einen kleinen Leistungsschub sorgen kann d.get.

SzieberthAdam
quelle
1
Könnten Sie bitte die Syntax in Zeile 2 erläutern? Ich lerne gerade Python 3 und würde dieses gerne verstehen.
Serge
2
Sicher, aber es wäre einfacher, wenn ich wüsste, was Sie nicht verstehen. [x for x in iterable]ist ein Python-Listenverständnis (Google), das in Python zum Erstellen von Listen sehr verbreitet und effizient ist. (k, d[k])ist ein Tupel mit zwei Elementen, das zweite Element ( d[k]) ist der Wert aus dem Wörterbuch. sorted()ist eine integrierte Funktion, die die nach den Werten sortierten Schlüssel des Wörterbuchs zurückgibt. Verwenden Sie key=d.getes den Schlüssel meiner Antwort, der nicht trivial zu wissen ist. Es ist wichtig, die eingebauten Funktionen zu kennen. Ich hoffe das hat geholfen.
SzieberthAdam
Vielen Dank! Das [x for x in iterable]"Listenverständnis" fehlte im Einführungskurs. Lesen Sie jetzt darüber (war schwer zu finden, den Namen nicht zu kennen).
Serge
29
from collections import OrderedDict
from operator import itemgetter    

d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
print(OrderedDict(sorted(d.items(), key = itemgetter(1), reverse = True)))

druckt

OrderedDict([('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)])

Obwohl aus Ihrem letzten Satz hervorgeht, dass eine Liste von Tupeln gut funktionieren würde, z

from operator import itemgetter  

d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
for key, value in sorted(d.items(), key = itemgetter(1), reverse = True):
    print(key, value)

welche druckt

bb 4
aa 3
cc 2
dd 1
Paul Draper
quelle
Danke für Ihre Hilfe. Ich dachte, dass eine der Lösungen ähnlich sein wird.
1
dictbehält jetzt die Einfügereihenfolge bei, daher gibt es keinen Grund zur VerwendungOrderedDict
Boris
1
Ich kann mir zwei Gründe vorstellen: Erstens wird deutlich, dass Sie sich für die Reihenfolge interessieren, zweitens kann jemand Ihren Code auf einem älteren Interpreter ausführen, und es ist kein gutes Ergebnis, wenn er sich stillschweigend schlecht benimmt.
Plugwash
16

Mit einem Wörterbuchverständnis können Sie nach Werten in umgekehrter Reihenfolge (größte bis kleinste) sortieren :

{k: d[k] for k in sorted(d, key=d.get, reverse=True)}
# {'b': 4, 'a': 3, 'c': 2, 'd': 1}

Wenn Sie nach Werten in aufsteigender Reihenfolge sortieren möchten (kleinste bis größte)

{k: d[k] for k in sorted(d, key=d.get)}
# {'d': 1, 'c': 2, 'a': 3, 'b': 4}

Wenn Sie nach den Schlüsseln in aufsteigender Reihenfolge sortieren möchten

{k: d[k] for k in sorted(d)}
# {'a': 3, 'b': 4, 'c': 2, 'd': 1}

Dies funktioniert unter CPython 3.6+ und jeder Implementierung von Python 3.7+, da Wörterbücher die Einfügereihenfolge beibehalten.

Boris
quelle
11

Eine andere Möglichkeit besteht darin, einen Lambda-Ausdruck zu verwenden. Abhängig von der Interpreter-Version und davon, ob Sie ein sortiertes Wörterbuch oder sortierte Schlüsselwert-Tupel erstellen möchten (wie dies beim OP der Fall ist), ist dies möglicherweise sogar schneller als die akzeptierte Antwort.

d = {'aa': 3, 'bb': 4, 'cc': 2, 'dd': 1}
s = sorted(d.items(), key=lambda x: x[1], reverse=True)

for k, v in s:
    print(k, v)
Bede Constantinides
quelle
1
Während Ihr Code funktioniert, glaube ich nicht, dass Wörterbücher die Artikel garantiert in der Reihenfolge zurückgeben, in der sie hinzugefügt wurden.
Ivan
2
@Ivan Danke - Ich habe die überflüssige Verwendung von dict () hier entfernt, obwohl in CPython 3.6+ dict die Reihenfolge beibehält und dies wahrscheinlich in naher Zukunft zu einer Sprachfunktion wird ( docs.python.org/3) /whatsnew/3.6.html )
Bede Constantinides
Danke, es ist interessant zu wissen. Auch - am Ende können Sie einfach print(s)anstelle einer Schleife tun :)
Ivan
1
dicts Ordnung in allen Pythons beginnend mit 3.7
Boris
1
Tatsächlich sind es weniger als 10%. Ich bekomme 54 ms gegenüber 57,3 ms in Python 3.8.6 mit einem Wörterbuch mit 100.000 Elementen, aber technisch immer noch langsamer. Ich denke, Sie sollten sie entfernen, es ist keine lohnende Optimierung.
Boris vor
10

Um das Wörterbuch zu sortieren, könnten wir ein Operatormodul verwenden. Hier ist die Dokumentation des Bedienermoduls.

import operator                             #Importing operator module
dc =  {"aa": 3, "bb": 4, "cc": 2, "dd": 1}  #Dictionary to be sorted

dc_sort = sorted(dc.items(),key = operator.itemgetter(1),reverse = True)
print dc_sort

Die Ausgabesequenz ist eine sortierte Liste:

[('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)]

Wenn wir nach Schlüsseln sortieren wollen, können wir davon Gebrauch machen

dc_sort = sorted(dc.items(),key = operator.itemgetter(0),reverse = True)

Die Ausgabesequenz lautet:

[('dd', 1), ('cc', 2), ('bb', 4), ('aa', 3)]
Reck
quelle
Die Antwort von Paul Draper verwendet bereits Operator ... importiert nur nicht die gesamte Bibliothek
Salvatore Cosentino
0

Um ein Wörterbuch zu sortieren und es anschließend als Wörterbuch zu verwenden, können Sie OrderedDict aus der Standardbibliothek verwenden.

Wenn Sie dies nicht benötigen, empfehlen wir Ihnen, die Sortierfunktionen zu überdenken, die Ihnen eine Liste mit Tupeln hinterlassen. Welche Ausgabe wollten Sie, wenn nicht eine geordnete Liste von Schlüssel-Wert-Paaren (Tupeln)?

Andrew Gorcester
quelle
dictbehält jetzt die Einfügereihenfolge bei, daher gibt es keinen Grund zur VerwendungOrderedDict
Boris