it-swarm.com.de

Wörterbücher: Wie werden Schlüssel/Werte in der angegebenen Reihenfolge gehalten?

Ich habe ein Wörterbuch, das ich in einer bestimmten Reihenfolge angegeben habe, und möchte es ständig in dieser Reihenfolge halten. Die Schlüssel/Werte können aufgrund ihres Werts nicht wirklich in der richtigen Reihenfolge gehalten werden. Ich möchte nur, dass sie in der Reihenfolge stehen, in der ich sie deklariert habe.

Also wenn ich das Wörterbuch habe:

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}

Es ist nicht in dieser Reihenfolge, wenn ich es sehe oder durchläuft. Gibt es eine Möglichkeit, sicherzustellen, dass Python die explizite Reihenfolge einhält, in der ich die Schlüssel/Werte deklariert habe?

246
roflwaffle
from collections import OrderedDict
OrderedDict((Word, True) for Word in words)

enthält 

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

Wenn die Werte True (oder ein anderes unveränderliches Objekt) sind, können Sie auch Folgendes verwenden:

OrderedDict.fromkeys(words, True)
159
eumiro

Anstatt den theoretischen Teil zu erklären, werde ich ein einfaches Beispiel geben.

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}
151
Mohit Dabas

Ab Python 3.6 behält der Standardtyp dict standardmäßig die Einfügereihenfolge bei.

Definieren

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

führt zu einem Wörterbuch mit den Schlüsseln in der im Quellcode angegebenen Reihenfolge.

Dies wurde durch die Verwendung eines einfachen Arrays mit Ganzzahlen für die Sparse-Hash-Tabelle erreicht, wobei diese Ganzzahlen in ein anderes Array indexieren, in dem die Schlüssel-Wert-Paare (plus den berechneten Hash) gespeichert werden. Dieses letztere Array speichert die Elemente in der Reihenfolge des Einfügens, und die gesamte Kombination verbraucht tatsächlich weniger Speicher als die in Python 3.5 und zuvor verwendete Implementierung. Weitere Informationen finden Sie im ursprünglichen Ideenbeitrag von Raymond Hettinger .

In 3.6 wurde dies noch als Implementierungsdetail betrachtet. Siehe What's New in Python 3.6 Dokumentation :

Der auftragserhaltende Aspekt dieser neuen Implementierung wird als Implementierungsdetail betrachtet und sollte nicht als verlässlich angesehen werden (dies kann sich in der Zukunft ändern. Es ist jedoch erwünscht, dass diese neue Diktimplementierung für einige Versionen in der Sprache vorliegt, bevor die Sprachspezifikation geändert wird Um eine bestandserhaltende Semantik für alle aktuellen und zukünftigen Python-Implementierungen zu verlangen, hilft dies auch dabei, die Abwärtskompatibilität mit älteren Sprachversionen, in denen noch eine zufällige Iterationsreihenfolge besteht (zB Python 3.5), zu erhalten.

Python 3.7 erhöht dieses Implementierungsdetail auf eine -Sprachenspezifikation. Es ist jetzt zwingend erforderlich, dass dict die Reihenfolge in allen Python-Implementierungen beibehält, die mit dieser Version oder neuer kompatibel sind. Siehe die Aussprache durch das BDFL .

In bestimmten Fällen möchten Sie möglicherweise noch die collections.OrderedDict()-Klasse verwenden, da sie einige zusätzliche Funktionen zusätzlich zum Standardtyp dict bietet. B. umkehrbar (dies erstreckt sich auf Sichtobjekte ) und unterstützt die Neuordnung (über die move_to_end()-Methode ).

129
Martijn Pieters

Beachten Sie, dass diese Antwort für Python-Versionen vor Python3.7 gilt. CPython 3.6 behält die Einfügereihenfolge unter den meisten Umständen als Implementierungsdetail bei. Ab Python 3.7 wurde erklärt, dass Implementierungen die Einfügungsreihenfolge aufrechterhalten MÜSSEN, damit sie kompatibel sind.


python-Wörterbücher sind nicht geordnet. Wenn Sie ein geordnetes Wörterbuch wünschen, versuchen Sie Collections.OrderedDict .

Beachten Sie, dass OrderedDict in Python 2.7 in die Standardbibliothek aufgenommen wurde. Wenn Sie eine ältere Version von Python haben, finden Sie unter ActiveState Rezepte für geordnete Wörterbücher.

29
mgilson

Wörterbücher verwenden eine Reihenfolge, die die Suche effizienter macht, und Sie können dies nicht ändern.

Sie können einfach eine Liste von Objekten (in einem einfachen Fall ein Tupel mit 2 Elementen oder sogar eine Klasse) verwenden und Elemente an das Ende anhängen. Sie können dann die lineare Suche verwenden, um Elemente darin zu suchen.

Alternativ können Sie eine andere Datenstruktur erstellen oder verwenden, die mit der Absicht erstellt wurde, die Reihenfolge zu erhalten.

12
Fire Lancer

Ich bin auf diesen Beitrag gestoßen, als ich versuchte herauszufinden, wie man OrderedDict zum Laufen bringt. PyDev für Eclipse konnte OrderedDict überhaupt nicht finden, also entschied ich mich, ein Tuple aus den Schlüsselwerten meines Wörterbuchs zu machen, da ich möchte, dass sie bestellt werden. Als ich meine Liste ausgeben musste, iterierte ich nur die Werte des Tuples und steckte den iterierten 'Schlüssel' vom Tuple in das Wörterbuch ein, um meine Werte in der Reihenfolge abzurufen, in der ich sie brauchte.

beispiel:

test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_Tuple = ( 'val1', 'val2', 'val3', 'val4')
for key in test_Tuple: print(test_dict[key])

Es ist ein bisschen umständlich, aber ich habe Zeitdruck und es ist der Workaround, den ich gefunden habe.

hinweis: Die Liste der Listen, die jemand anderes vorgeschlagen hat, ist für mich nicht wirklich sinnvoll, da Listen geordnet und indiziert sind (und auch eine andere Struktur als Wörterbücher sind).

8
smushface

Mit einem Wörterbuch können Sie nicht wirklich machen, was Sie wollen. Sie haben bereits das Wörterbuch d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10} erstellt. Ich habe festgestellt, dass es keine Möglichkeit gibt, in Ordnung zu bleiben, wenn es bereits erstellt wurde. Was ich gemacht habe, war eine Json-Datei statt mit dem Objekt zu erstellen:

{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}

Ich benutzte:

r = json.load(open('file.json'), object_pairs_hook=OrderedDict)

dann verwendet:

print json.dumps(r)

verifizieren.

6
nealous3

wenn Sie ein Wörterbuch in einer bestimmten Reihenfolge haben möchten, können Sie auch eine Liste mit Listen erstellen, wobei der erste Eintrag der Schlüssel und der zweite Eintrag der Wert. Beispiel 

>>> list =[[1,2],[2,3]]
>>> for i in list:
...     print i[0]
...     print i[1]

1
2
2
3
2
pelos

Ich hatte ein ähnliches Problem bei der Entwicklung eines Django-Projekts. Ich konnte OrderedDict nicht verwenden, da ich eine alte Version von Python verwendete. Die einfache Lösung war die Verwendung der SortedDict-Klasse von Django:

https://code.djangoproject.com/wiki/SortedDict

2
Evan

Im Allgemeinen können Sie eine Klasse entwerfen, die sich wie ein Wörterbuch verhält, indem Sie hauptsächlich die Methoden __contains__, __getitem__, __delitem__, __setitem__ und einige andere implementieren. Diese Klasse kann ein beliebiges Verhalten haben, z. B. das Aufteilen eines sortierten Iterators über die Tasten ...

2
Rasmus Kaj
from collections import OrderedDict
list1 = ['k1', 'k2']
list2 = ['v1', 'v2']
new_ordered_dict = OrderedDict(Zip(list1, list2))
print new_ordered_dict
# OrderedDict([('k1', 'v1'), ('k2', 'v2')])
1
user11502624

Sie können dasselbe tun, was ich für das Wörterbuch getan habe.

Erstellen Sie eine Liste und ein leeres Wörterbuch:

dictionary_items = {}
fields = [['Name', 'Himanshu Kanojiya'], ['email id', '[email protected]']]
l = fields[0][0]
m = fields[0][1]
n = fields[1][0]
q = fields[1][1]
dictionary_items[l] = m
dictionary_items[n] = q
print dictionary_items
0

Eine andere Alternative ist die Verwendung von Pandas dataframe , da die Reihenfolge und die Indexpositionen der Elemente in einer diktatartigen Struktur garantiert werden.

0
Ville