Wie füge ich zwei Wörterbücher in einem Ausdruck zusammen?
Habe ich zwei Python-Wörterbücher, und ich möchte zu schreiben, die einen einzigen Ausdruck, gibt diese zwei Wörterbücher, zusammengeführt. Die update()
Methode wäre das, was ich brauche, wenn es zurückgegeben, dessen Ergebnisse anstelle der änderung eines dict.
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = x.update(y)
>>> print(z)
None
>>> x
{'a': 1, 'b': 10, 'c': 11}
Wie kann ich erreichen, dass die endgültigen zusammengeführten dict in z
nicht x
?
(Extra-klar, die last-man-gewinnt-Konflikt-Umgang mit dict.update()
ist das, was ich Suche.)
InformationsquelleAutor der Frage Carl Meyer | 2008-09-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wörterbücher für
x
undy
z
wird eine zusammengeführte dictionary mit Werten ausy
ersetzen diejenigen vomx
.In Python 3.5 oder höher :
In Python 2, (oder 3.4 oder niedriger) schreiben Sie eine Funktion:
und
Erklärung
Sagen, Sie haben zwei dicts und Sie Zusammenführen möchten Sie in ein neues dict-ohne Veränderung des original-dicts:
Das gewünschte Ergebnis zu bekommen ist ein neues Wörterbuch (
z
) mit den Werten verschmolzen, und die zweite dict-Werte überschreiben, die von der ersten.Eine neue syntax für diese, schlug in PEP 448 und lieferbar als Python-3.5ist
Und es ist in der Tat ein einzelner Ausdruck. Es ist nun zu zeigen, wie die Umsetzung in der release-Zeitplan für 3.5, PEP 478und hat es nun seinen Weg in Was ist Neu in Python 3.5 Dokument.
Da jedoch viele Organisationen sind immer noch auf Python 2 Sie möchten, können Sie dies tun, in einem rückwärts kompatiblen Art und Weise. Die klassisch-Pythonic way, verfügbar in Python 2 und Python 3.0-3.4, tun dies als ein zwei-Schritt-Prozess:
In beiden Ansätzen
y
kommen zweiten, und Ihre Werte ersetzenx
's Werte, so'b'
auf3
in unserem letzten Ergebnis.Noch nicht auf Python 3.5, aber ein einzelnen Ausdruck
Wenn Sie noch nicht auf Python 3.5 oder schreiben zu müssen-rückwärts-kompatiblen code, und Sie wollen dies in einem einzelnen Ausdruckdie performant, während der richtige Ansatz ist, um es in eine Funktion:
und dann haben Sie einen einzigen Ausdruck:
Können Sie auch eine Funktion zum Zusammenführen einer unbestimmten Anzahl von dicts, von null auf eine sehr große Anzahl:
Diese Funktion wird in Python 2 und 3 für alle dicts. z.B. gegeben dicts
a
zug
:- und Schlüssel-Wert-Paare in
g
Vorrang vor dictsa
zuf
und so weiter.Kritiken von Anderen Antworten
Nicht verwenden, was Sie in der früher akzeptierte Antwort:
In Python 2 erstellen Sie zwei Listen im Speicher für jeden dict-erstellen Sie eine Dritte Liste im Speicher mit einer Länge gleich der Länge der beiden ersten zusammen, und legen Sie alle drei Listen zu erstellen, die der dict. In Python 3, wird dies scheiternweil Sie das hinzufügen von zwei
dict_items
Objekte zusammen, nicht zwei Listen -und Sie würden explizit erstellen Sie Listen, z.B.
z = dict(list(x.items()) + list(y.items()))
. Dies ist eine Verschwendung von Ressourcen und Rechenleistung.Ähnlich, wobei die union der
items()
in Python 3 (viewitems()
in Python 2.7) wird auch scheitern, wenn die Werte unhashable Objekte (wie Listen, zum Beispiel). Auch wenn deine Werte sind hashable, da-Sätze sind semantisch ungeordnete, das Verhalten ist undefiniert in Bezug auf die Rangfolge. So tun Sie das nicht:Dieses Beispiel zeigt, was passiert, wenn Werte unhashable:
Hier ist ein Beispiel, wo y sollte Vorrang haben, sondern der Wert von x wird beibehalten, aufgrund der willkürlichen Reihenfolge der Sätze:
Anderen hack sollten Sie nicht verwenden:
Diese nutzt die
dict
Konstruktor, und ist sehr schnell, und Speicher effizient (sogar etwas mehr-so, als unsere zwei-Schritt-Prozess), aber es sei denn, Sie wissen genau, was hier passiert (das heißt, die zweite dict übergeben wird als Schlüsselwort-Argumente an die dict-Konstruktor), es ist schwer zu Lesen, es ist nicht die beabsichtigte Verwendung, und so ist es nicht Pythonic.Hier ist ein Beispiel für die Nutzung als saniert in django.
Dicts geplanten hashable-Tasten (z.B. frozensets oder Tupel), aber versagt diese Methode in Python 3 bei der Schlüsselübergabe, sind keine strings.
Aus der MailinglisteGuido van Rossum, der Schöpfer der Sprache, schrieb:
und
Es ist mein Verständnis (wie auch das Verständnis für die Schöpfer der Sprache), dass die beabsichtigte Nutzung für
dict(**y)
ist für die Erstellung von dicts für eine bessere Lesbarkeit, z.B.:statt
Reaktion auf Kommentare
Wieder, es doesn ' T Arbeit für 3, wenn die Tasten sind nicht-Streichern. Der implizite Aufruf Vertrages ist, dass namespaces nehmen normalen dicts, während der Benutzer muss nur pass-Schlüsselwort-Argumente sind Zeichenfolgen. Alle anderen callables durchgesetzt.
dict
brach diese Konsistenz in Python 2:Diese Inkonsistenz wurde schlecht gegeben, andere Implementierungen von Python (Pypy, Jython, IronPython). So war es fest in Python 3, als diese Nutzung könnte eine wichtige änderung.
Ich Ihnen zu, dass es bösartig ist Inkompetenz absichtlich code schreiben, das funktioniert nur in einer version, die Sprache oder das funktioniert nur bei bestimmten willkürlichen Einschränkungen.
Anderen Kommentar:
Meine Antwort:
merge_two_dicts(x, y)
tatsächlich scheint viel klarer zu mir, wenn wir sind tatsächlich besorgt um die Lesbarkeit zu verbessern. Und es ist nicht aufwärtskompatibel, da Python 2 ist zunehmend veraltet.Weniger Performant, Aber Korrekte Ad-hocs
Diese Ansätze sind weniger performant, aber Sie werden das richtige Verhalten.
Sie werden viel weniger performant als
copy
undupdate
oder die neuen Auspacken, weil Sie iterativ durch die einzelnen Schlüssel-Wert-paar auf einer höheren Ebene der Abstraktion, aber Sie tun hinsichtlich der Reihenfolge der Priorität (letztere dicts haben Vorrang)Können Sie auch die Kette dicts manuell innerhalb eines dict-comprehension:
oder in python 2.6 (und vielleicht schon 2.4 wenn die generator expressions vorgestellt wurden):
itertools.chain
wird die Kette mit Iteratoren über die Schlüssel-Wert-Paare in der richtigen Reihenfolge:Performance-Analyse
Ich werde nur zu tun, die performance-Analyse der Nutzungen bekannt, die sich korrekt Verhalten.
Folgende geschieht auf Ubuntu 14.04
In Python 2.7 (system Python):
In Python 3.5 (deadsnakes PPA):
Ressourcen auf Wörterbücher
InformationsquelleAutor der Antwort Aaron Hall
In Ihrem Fall, was Sie tun können, ist:
Diese wird, wie Sie es wollen, legen Sie die endgültige dict in
z
und stellen Sie den Wert für den Schlüsselb
ordnungsgemäß überschrieben, die von der zweiten (y
) dict-Wert:Wenn Sie mit Python 3, es ist nur ein wenig komplizierter. Erstellen
z
:InformationsquelleAutor der Antwort Thomas Vander Stichele
Alternative:
InformationsquelleAutor der Antwort Matthew Schinckel
Einem anderen, knapperen, option:
Hinweis: dieser hat sich zu einer beliebten Antwort, aber es ist wichtig, darauf hinzuweisen, dass, wenn
y
hat alle nicht-string-Schlüssel, die Tatsache, dass dies überhaupt funktioniert, ist ein Missbrauch einer CPython-Implementierung detail, und es funktioniert nicht in Python 3, oder in PyPy, IronPython oder Jython. Auch, Guido ist kein fan. Also ich kann nicht empfehlen, diese Technik für vorwärts-kompatibel oder cross-Implementierung portabler code, der wirklich bedeutet, Sie sollten ganz vermieden werden.InformationsquelleAutor der Antwort Carl Meyer
Diese wahrscheinlich nicht eine beliebte Antwort, aber Sie fast sicher nicht wollen, dies zu tun. Wenn Sie möchten, eine Kopie, ein merge ist, dann verwenden Sie kopieren (oder deepcopyje nachdem, was Sie wollen) und dann zu aktualisieren. Die zwei Zeilen code sehr viel besser lesbar - mehr Pythonic - als die einzige Zeile die Schöpfung mit .Elemente() + .Elemente(). Explizit ist besser als implizit.
Darüber hinaus, wenn Sie verwenden .Elemente() (vor Python 3.0), erstellen Sie eine neue Liste, die die Elemente enthält, die aus der dict. Wenn Ihre Wörterbücher sind groß, dann ist das ziemlich viel Aufwand (zwei große Listen, die werden weggeworfen, sobald die zusammengeführten dict erstellt wird). update() können effizienter arbeiten, weil es laufen kann, durch die zweite dict-Element-by-Element.
In Bezug auf Zeit:
IMO die winzige Abschwächung zwischen den ersten beiden ist es Wert für die Lesbarkeit. Darüber hinaus Schlüsselwort-Argumente für die Wörterbuch-Schöpfung wurde nur Hinzugefügt, in Python 2.3, in der Erwägung, dass copy() und update() funktioniert in älteren Versionen.
InformationsquelleAutor der Antwort Tony Meyer
In einem follow-up zu beantworten, fragte Sie über die relative performance dieser zwei alternativen:
Auf meinem Rechner, mindestens (eine ziemlich gewöhnliche x86_64 running Python 2.5.2), alternative
z2
ist nicht nur kürzer und einfacher, sondern auch deutlich schneller. Sie können dies überprüfen, für sich selbst mit demtimeit
Modul, kommt mit Python.Beispiel 1: identische Wörterbücher mapping 20 aufeinander folgenden ganzen zahlen auf sich selbst:
z2
gewinnt durch einen Faktor von 3,5 oder so. Verschiedene Wörterbücher scheinen zu ergeben Recht unterschiedliche Ergebnisse, aberz2
scheint immer weiter kommen. (Wenn Sie inkonsistente Ergebnisse für die gleichen testen, versuchen, die vorbeifahrenden-r
mit einer Zahl größer als der Standardwert 3.)Beispiel 2: nicht-überlappende Wörterbücher mapping 252 kurze Zeichenketten in ganze zahlen und Umgekehrt:
z2
gewinnt, indem es sich etwa um den Faktor 10. Das ist ein ziemlich großer Gewinn in meinem Buch!Nach einem Vergleich dieser beiden, ich fragte mich, ob
z1
's schlechte Leistung zurückzuführen sein könnten, der Aufwand für den Bau der zwei-posten-Listen, die wiederum führte mich zu Fragen, ob diese Variante besser laufen könnte:Ein paar schnelle tests, z.B.
führen mich zu dem Schluss, dass
z3
ist etwas schneller als diez1
aber nicht annähernd so schnell, wiez2
. Definitiv nicht alle extra eingeben.Diese Diskussion ist noch etwas wichtiges fehlt, das ist ein performance-Vergleich dieser alternativen mit den "offensichtlichen" Weg der Zusammenführung von zwei Listen: mithilfe des
update
Methode. Um zu versuchen, um die Dinge auf Augenhöhe mit den Ausdrücken, von denen keiner ändern x oder y, ich werde eine Kopie von x, anstatt es, zu ändern, wie folgt:Ein typisches Ergebnis:
In anderen Worten,
z0
undz2
zu haben scheinen, im wesentlichen identische Leistung. Denken Sie, könnte dies ein Zufall sein? Ich nicht....In der Tat, ich würde so weit gehen zu behaupten, dass es unmöglich ist, für Reine Python-code zu tun, besser als dieser. Und wenn Sie das tun können wesentlich besser in eine C-extension module, Stell ich mir die Python-Leute könnten interessiert sein, die Ihren code (oder eine variation auf Ihrem Ansatz) in der Python-Kern. Python verwendet
dict
an vielen Orten; die Optimierung der Operationen ist eine große Sache.Sie können auch schreiben dies als
wie Tony tut, aber (nicht überraschend), der Unterschied in der notation stellt sich heraus, nicht um irgendeine messbare Wirkung auf die Leistung. Je nachdem, was gut aussieht auf Sie. Natürlich, er hat völlig zu Recht darauf hin, dass die zwei-und GuV-version ist viel einfacher zu verstehen.
InformationsquelleAutor der Antwort zaphod
Ich wollte etwas ähnliches, aber mit der Fähigkeit, um anzugeben, wie die Werte, auf doppelte Schlüssel zusammengeführt wurden, so dass ich gehackt (aber nicht stark testen). Natürlich ist dies nicht ein einzelner Ausdruck, aber es ist eine einzelne Funktion aufrufen.
InformationsquelleAutor der Antwort rcreswick
In Python 3 können Sie Sammlungen.ChainMap die Gruppen mehrere dicts oder anderen Zuordnungen, die zusammen zu einem einzigen, aktualisierbare Ansicht:
InformationsquelleAutor der Antwort Raymond Hettinger
Rekursiv/tief-update ein dict
Demonstration:
Ausgänge:
Dank rednaw bearbeitet werden.
InformationsquelleAutor der Antwort Stan
Die beste version, die ich denken konnte, während Sie nicht mit kopieren würde:
Es ist schneller als
dict(x.items() + y.items())
aber nicht so schnell wien = copy(a); n.update(b)
zumindest auf CPython. Diese version funktioniert auch in Python 3, wenn Sie änderniteritems()
zuitems()
die erfolgt automatisch durch das 2to3-tool.Mir persönlich gefällt diese version am besten, weil es beschreibt ziemlich gut, was ich will in einer einzigen funktionalen syntax. Das einzige kleine problem ist, dass es nicht völlig offensichtlich, dass die Werte von y Vorrang vor den Werten von x, aber ich glaube nicht, es ist schwierig, das herauszufinden.
InformationsquelleAutor der Antwort driax
Python-3.5 (PEP 448) ermöglicht eine schönere syntax option:
Oder sogar
InformationsquelleAutor der Antwort Bilal Syed Hussain
Für die Elemente mit den Schlüsseln in den beiden Wörterbüchern ('b') können Sie Steuern, welche man im Endeffekt in der Ausgabe durch setzen, dass man letzten.
InformationsquelleAutor der Antwort Greg Hewgill
Während die Frage wurde bereits mehrfach beantwortet,
diese einfache Lösung für das problem wurde nicht gelistet.
Ist es, so schnell wie z0 und das böse, das z2 erwähnt, aber leicht zu verstehen und zu ändern.
InformationsquelleAutor der Antwort phobie
Unter solchen zwielichtigen und zweifelhaften Antworten, dieses glänzende Beispiel ist der eine und einzige gute Weise zu verschmelzen dicts in Python, unterstützt von Diktator für das Leben Guido van Rossum selbst! Jemand anderes schlug vor, die Hälfte davon, aber nicht steckte es in eine Funktion.
gibt:
InformationsquelleAutor der Antwort Sam Watkins
Wenn Sie denken, dass Lambda-Ausdrücke sind böse, dann Lesen Sie nicht weiter.
Wie gewünscht, können Sie die schnelle und Speicher-effiziente Lösung mit einem Ausdruck:
Wie oben angedeutet, mit zwei Linien oder schreiben Sie eine Funktion ist möglicherweise ein besserer Weg zu gehen.
InformationsquelleAutor der Antwort EMS
In Python ist3, die
items
Methode gibt nicht länger eine Listesondern eine Ansichtdie wirkt wie ein set. In diesem Fall müssen Sie die set-union, da die Verkettung mit+
nicht:Für Python ist3-wie Verhalten in der version 2.7, die
viewitems
Methode sollte funktionieren, stattitems
:Ich bevorzuge diese notation sowieso, da es scheint, mehr Natürliche zu denken, der Sie als union-operation eher als Verkettung (wie der Titel zeigt).
Edit:
Ein paar mehr Punkte für python 3. Beachten Sie zunächst, dass die
dict(x, **y)
trick funktioniert nicht in python 3, es sei denn, die Schlüssel iny
sind strings.Ebenfalls, Raymond Hettinger ist Chainmap Antwort ist ziemlich elegant, da es kann eine beliebige Anzahl von dicts als Argumente, aber von den docs es sieht aus wie es nacheinander sieht durch Sie eine Liste aller dicts für jede Suche:
Diese können Sie verlangsamen, wenn Sie eine Menge von verweisen in Ihrem Antrag:
Also etwa eine Größenordnung langsamer, für lookups. Ich bin ein fan von Chainmap, sieht aber weniger praktisch ist, wo es möglicherweise viele lookups.
InformationsquelleAutor der Antwort beardc
Werden pythonic. Verwenden Sie eine Verständnis:
InformationsquelleAutor der Antwort Robino
Missbrauch führt zu einem ein-Ausdruck Lösung für Matthew ' s Antwort:
Sie sagte, Sie wollte ein Ausdruck, so dass ich missbraucht
lambda
binden einen Namen und Tupel zu überschreiben lambda-Ausdruck einschränken. Fühlen Sie sich frei, zu kriechen.Könnten Sie dies auch tun, natürlich, wenn Sie kümmern sich nicht um Sie zu kopieren:
InformationsquelleAutor der Antwort Claudiu
Einfache Lösung mit itertools, bewahrt Bestellung (letztere dicts haben Vorrang)
Und es Verwendung:
InformationsquelleAutor der Antwort reubano
Zwei Wörterbücher
n Wörterbücher
sum
hat schlechte Leistung. Sehen https://mathieularose.com/how-not-to-flatten-a-list-of-lists-in-python/InformationsquelleAutor der Antwort Mathieu Larose
Obwohl die Antworten waren gut für diese flachen Wörterbuch keine der Methoden definiert hier eigentlich mache einen tiefen Wörterbuch Zusammenführen.
Beispiele:
Würde man erwarten, eine Wirkung von etwas wie dies:
Stattdessen bekommen wir dies:
Das " man " - Eintrag haben sollte, hatte 'depth_2' und 'extra' als Artikel in seinem Wörterbuch, wenn es war wirklich ein merge.
Mit Kette auch nicht funktioniert:
Ergebnisse in:
Das Tiefe verschmelzen, dass rcwesick gab auch erzeugt das gleiche Ergebnis.
Ja, es wird funktionieren, zum Zusammenführen der Probe Wörterbücher, aber keiner von Ihnen hat einen generischen Mechanismus zu verschmelzen. Ich werde aktualisieren diese später einmal Schreibe ich eine Methode, die ein wahres verschmelzen.
InformationsquelleAutor der Antwort Thanh Lim
In python 3:
Out:
Docs: https://docs.python.org/3/library/collections.html#collections.ChainMap:
InformationsquelleAutor der Antwort Skyduy
InformationsquelleAutor der Antwort John La Rooy
Für Python 2 :
Für Python 3:
Es gibt Ausgabe:
{'a': 1, 'c': 11, 'b': 10}
InformationsquelleAutor der Antwort Kalpesh Dusane
Zeichnung auf Ideen hier und anderswo habe ich Begriffen, eine Funktion:
Nutzung (getestet in python 3):
Könnte man eine lambda statt.
InformationsquelleAutor der Antwort Bijou Trouvaille
Ich habe das problem mit Lösungen aufgeführt, um das Datum, die zusammengeführt Wörterbuch, den Wert für den Schlüssel "b" 10, aber, zu meiner Art zu denken, es sollte sein 12.
In diesem Sinne präsentiere ich Folgendes:
Ergebnisse:
InformationsquelleAutor der Antwort upandacross
(Für Python2.7* nur; es gibt einfachere Lösungen für Python ist3*.)
Wenn Sie nicht abgeneigt zu importieren einer standard-Bibliothek Modul, die Sie tun können,
(Die
or a
bit in derlambda
ist notwendig, weildict.update
gibt immerNone
auf Erfolg.)InformationsquelleAutor der Antwort kjo
In Python 3.5 können Sie verwenden, entpacken Sie
**
um neue Wörterbuch.Diese Methode hat keine war, zeigte sich in der Vergangenheit Antworten. Auch, es ist besser
{}
stattdict()
. Da{}
ist ein python-wörtlich und imdict()
beinhaltet einen Aufruf der Funktion.InformationsquelleAutor der Antwort levi
Können Sie
toolz.merge([x, y])
.InformationsquelleAutor der Antwort Mike Graham
Mit einem dict-comprehension, können Sie
gibt
Beachten Sie die syntax für
if else
im VerständnisInformationsquelleAutor der Antwort octoback