Wie kann ein geordnetes Wörterbuch (OD) richtig initialisiert werden, damit die Reihenfolge der Anfangsdaten beibehalten wird?
from collections import OrderedDict
# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1})
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])
# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])
Frage:
Wird
OrderedDict
die Reihenfolge einer Liste von Tupeln oder eines Tupels von Tupeln oder eines Tupels von Listen oder einer Liste von Listen usw. beibehalten, die zum Zeitpunkt der Initialisierung übergeben wurden (2. und 3. Beispiel oben)?Wie kann man überprüfen, ob
OrderedDict
tatsächlich eine Bestellung aufrechterhalten wird? Da adict
eine unvorhersehbare Reihenfolge hat, was ist, wenn meine Testvektoren glücklicherweise dieselbe Anfangsreihenfolge haben wie die unvorhersehbare Reihenfolge eines Diktats? Wennd = OrderedDict({'b':2, 'a':1})
ich zum Beispiel nicht schreibed = OrderedDict({'a':1, 'b':2})
, kann ich fälschlicherweise den Schluss ziehen, dass die Reihenfolge erhalten bleibt. In diesem Fall habe ich herausgefunden, dass adict
alphabetisch geordnet ist, aber das ist möglicherweise nicht immer der Fall. Was ist ein zuverlässiger Weg, um anhand eines Gegenbeispiels zu überprüfen, ob eine Datenstruktur die Ordnung beibehält oder nicht, ohne wiederholt Testvektoren zu versuchen, bis einer bricht?
PS Ich lasse dies hier nur als Referenz : "Der OrderedDict-Konstruktor und die update () -Methode akzeptieren beide Schlüsselwortargumente, aber ihre Reihenfolge geht verloren, weil Pythons Funktionsaufrufsemantik die Schlüsselwortargumente mit einem regulären ungeordneten Wörterbuch übergibt."
PPS: Hoffentlich behält OrderedDict in Zukunft auch die Reihenfolge der kwargs bei (Beispiel 1): http://bugs.python.org/issue16991
quelle
OrderDict(b=2, a=1)
ist auch ein richtiger Weg. Siehe PEP 468 .Antworten:
Das OrderedDict behält jede Bestellung bei, auf die es Zugriff hat. Die einzige Möglichkeit, geordnete Daten zur Initialisierung an sie zu übergeben, besteht darin, eine Liste (oder allgemeiner eine iterierbare) von Schlüssel-Wert-Paaren zu übergeben, wie in Ihren letzten beiden Beispielen. Wie in der von Ihnen verlinkten Dokumentation angegeben, hat OrderedDict keinen Zugriff auf eine Reihenfolge, wenn Sie Schlüsselwortargumente oder ein Diktatargument übergeben, da dort eine Reihenfolge entfernt wird, bevor der OrderedDict-Konstruktor sie sieht.
Beachten Sie, dass die Verwendung eines Listenverständnisses in Ihrem letzten Beispiel nichts ändert. Es gibt keinen Unterschied zwischen
OrderedDict([(i,i) for i in l])
undOrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')])
. Das Listenverständnis wird ausgewertet und erstellt die Liste und wird übergeben; OrderedDict weiß nichts darüber, wie es erstellt wurde.quelle
Ja, das wird funktionieren. Per Definition wird eine Liste immer so geordnet, wie sie dargestellt wird. Dies gilt auch für das Listenverständnis. Die generierte Liste entspricht der Bereitstellung der Daten (dh die Quelle aus einer Liste ist deterministisch, stammt aus einer
set
oderdict
weniger).Sie behalten Ihre Quellliste mit 2 Tupeln als Referenz bei und verwenden diese als Testdaten für Ihre Testfälle, wenn Sie Komponententests durchführen. Durchlaufen Sie sie und stellen Sie sicher, dass die Reihenfolge eingehalten wird.
quelle
__hash__
. Speziell über denstr
Typ.OrderedDict
damit ich nicht den Aufwand habe, eine Liste in eine zu konvertierenOrderedDict
. Ich durchlaufe die Elemente einfach wie eine Liste anstelle eines Wörterbuchs.