Ich habe das:
d1 = OrderedDict([('a', '1'), ('b', '2')])
Wenn ich das mache:
d1.update({'c':'3'})
Dann bekomme ich folgendes:
OrderedDict([('a', '1'), ('b', '2'), ('c', '3')])
aber ich will das:
[('c', '3'), ('a', '1'), ('b', '2')]
ohne ein neues Wörterbuch zu erstellen.
python
python-3.x
dictionary
python-2.x
ordereddict
user2392209
quelle
quelle
Antworten:
In Python 2 gibt es dafür keine integrierte Methode. Wenn Sie dies benötigen, müssen Sie eine
prepend()
Methode / Funktion schreiben , die auf denOrderedDict
Interna mit O (1) -Komplexität arbeitet.Für Python 3.2 und höher, Sie sollten die Verwendung
move_to_end
Methode. Die Methode akzeptiert einlast
Argument, das angibt, ob das Element nach unten (last=True
) oder nach oben (last=False
) verschoben wirdOrderedDict
.Wenn Sie eine schnelle, schmutzige und langsame Lösung wünschen , können Sie einfach eine neue erstellen
OrderedDict
von Grund auf neu .Details zu den vier verschiedenen Lösungen:
Erweitern
OrderedDict
Sie eine neue Instanzmethode und fügen Sie sie hinzuDemo:
Standalone-Funktion zum Bearbeiten von
OrderedDict
ObjektenDiese Funktion macht dasselbe, indem sie das diktierte Objekt, den Schlüssel und den Wert akzeptiert. Ich persönlich bevorzuge die Klasse:
Demo:
Verwenden Sie
OrderedDict.move_to_end()
(Python> = 3.2)Python 3.2 führte die
OrderedDict.move_to_end()
Methode ein. Mit dieser Funktion können wir einen vorhandenen Schlüssel in O (1) -Zeit an jedes Ende des Wörterbuchs verschieben.Wenn wir ein Element einfügen und in einem Schritt nach oben verschieben müssen, können wir es direkt zum Erstellen eines
prepend()
Wrappers verwenden (hier nicht dargestellt).Erstelle ein neues
OrderedDict
- langsam !!!Wenn Sie dies nicht möchten und die Leistung kein Problem darstellt, können Sie am einfachsten ein neues Diktat erstellen:
Ausgabe:
quelle
c
bereits vorhanden, wird der alte Wert nicht aktualisiertmove_to_end
gibt es kein Python 3-Tag in der Frage,move_to_end
funktioniert nur in Python 3.2+. Ich werde meine Antwort aktualisieren, um die Python 3-basierte Lösung einzuschließen. Vielen Dank für das Update!move_to_front
, ist es vielleicht besser, einemove_to_front
Methode anstelle einer separatenprepend
Methode zu implementieren ? Dadurch wird Ihr Code portabler, wenn Sie jemals sowohl Python 2 als auch Python 3 von derselben Codebasis aus unterstützen müssen.dict_setitem=dict.__setitem__
als Parameterprepend
? Warum sollte / sollte man einen anderen Setter passieren?ordered_dict_prepend
oben. Wenn Sieordered_dict_prepend(d, 'c', 100)
zweimal aufrufen und versuchen, das resultierende Diktat zu drucken (indem Sie es einfachd
in die Python-Konsole eingeben), wird der Python-Prozess immer wieder gespeichert. Getestet mit Python 2.7.10BEARBEITEN (03.02.2019) Beachten Sie, dass die folgende Antwort nur bei älteren Versionen von Python funktioniert. In jüngerer Zeit wurde
OrderedDict
in C umgeschrieben. Außerdem berührt dies Attribute mit doppeltem Unterstrich, die verpönt sind.Ich habe gerade eine Unterklasse von
OrderedDict
in einem meiner Projekte für einen ähnlichen Zweck geschrieben. Hier ist das Wesentliche .Einfügevorgänge haben im
O(1)
Gegensatz zu den meisten dieser Lösungen auch eine konstante Zeit (Sie müssen die Datenstruktur nicht neu erstellen).quelle
TypeError: '_Link' object does not support indexing
wenn ich dies auf Python 3.4 verwende.OrderedDict
es ab Python 3.5 in C neu geschrieben wurde und diese Unterklasse das Tabu begangen hat, mit Interna herumzuspielen (tatsächlich die Namensverknüpfung umzukehren, um auf __ Eigenschaften zuzugreifen).Sie müssen eine neue Instanz von erstellen
OrderedDict
. Wenn Ihre Schlüssel eindeutig sind:Wenn nicht, achten Sie darauf, dass dieses Verhalten für Sie möglicherweise nicht erwünscht ist oder nicht:
quelle
OrderedDict
instabil wird?Wenn Sie wissen, dass Sie einen 'c'-Schlüssel möchten, den Wert aber nicht kennen, fügen Sie beim Erstellen des Diktats' c 'mit einem Dummy-Wert ein.
und ändern Sie den Wert später.
quelle
Dies ist jetzt mit move_to_end möglich (key, last = True)
https://docs.python.org/3/library/collections.html#collections.OrderedDict.move_to_end
quelle
FWIW Hier ist ein Quick-n-Dirty-Code, den ich zum Einfügen in eine beliebige Indexposition geschrieben habe. Nicht unbedingt effizient, aber es funktioniert vor Ort.
quelle
Möglicherweise möchten Sie eine andere Struktur verwenden, aber es gibt Möglichkeiten, dies in Python 2.7 zu tun .
d2 wird dann enthalten
Wie bereits von anderen erwähnt, in 3.2 Python können Sie verwenden
OrderedDict.move_to_end('c', last=False)
einen bestimmten Schlüssel nach dem Einsetzen zu bewegen.quelle
Wenn Sie Funktionen benötigen, die nicht vorhanden sind, erweitern Sie die Klasse einfach um Folgendes:
Nicht besonders effizient, funktioniert aber:
quelle
Ich würde vorschlagen
prepend()
, diesem reinen Python ActiveState-Rezept eine Methode hinzuzufügen oder daraus eine Unterklasse abzuleiten. Der Code dafür könnte ziemlich effizient sein, da die zugrunde liegende Datenstruktur für die Bestellung eine verknüpfte Liste ist.Aktualisieren
Um zu beweisen, dass dieser Ansatz machbar ist, finden Sie unten Code, der die vorgeschlagenen Aktionen ausführt. Als Bonus habe ich noch ein paar kleinere Änderungen vorgenommen, um sowohl in Python 2.7.15 als auch in 3.7.1 arbeiten zu können.
Eine
prepend()
Methode wurde der Klasse im Rezept hinzugefügt und in Bezug auf eine andere Methode implementiert, die mit dem Namenmove_to_end()
hinzugefügt wurde und dieOrderedDict
in Python 3.2 hinzugefügt wurde .prepend()
kann auch direkt implementiert werden, fast genau wie zu Beginn der Antwort von @Ashwini Chaudhary gezeigt - und dies würde wahrscheinlich dazu führen, dass es etwas schneller ist, aber das ist eine Übung für den motivierten Leser ...quelle
Ich habe eine Endlosschleife erhalten, als ich versucht habe, das Wörterbuch mit der Antwort @Ashwini Chaudhary mit Python zu drucken oder zu speichern
2.7
. Aber ich habe es geschafft, seinen Code ein wenig zu reduzieren und ihn hier zum Laufen zu bringen:quelle
Dies ist ein standardmäßiges, geordnetes Diktat, mit dem Sie Elemente an einer beliebigen Position einfügen und die verwenden können. Operator zum Erstellen von Schlüsseln:
quelle