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?
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)
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}
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 ).
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.
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.
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).
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.
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
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:
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 ...
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')])
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
Eine andere Alternative ist die Verwendung von Pandas dataframe
, da die Reihenfolge und die Indexpositionen der Elemente in einer diktatartigen Struktur garantiert werden.