Es wird eine neue Option geben, wenn Python 3.8 veröffentlicht wird ( geplant für 20. Oktober 2019 ), dank der PEP 572: Zuweisungsausdrücke . Der neue Operator für Zuweisungsausdrücke :=
ermöglicht es Ihnen, das Ergebnis der copy
und verwenden Sie es dennoch zum Aufruf von update
so dass der kombinierte Code ein einziger Ausdruck ist und nicht zwei Anweisungen, die sich ändern:
newdict = dict1.copy()
newdict.update(dict2)
zu:
(newdict := dict1.copy()).update(dict2)
und verhalten sich dabei in jeder Hinsicht identisch. Wenn Sie auch das Ergebnis zurückgeben müssen dict
(Sie fragten nach einem Ausdruck, der die dict
schafft und überträgt die oben genannten newdict
, gibt es aber nicht zurück, so dass man es nicht verwenden kann, um ein Argument an eine Funktion zu übergeben, so wie es bei myfunc((newdict := dict1.copy()).update(dict2))
), dann fügen Sie einfach or newdict
bis zum Ende (da update
devuelve None
was fehlerhaft ist, wird es dann auswerten und zurückgeben newdict
als Ergebnis des Ausdrucks):
(newdict := dict1.copy()).update(dict2) or newdict
Wichtiger Vorbehalt: Im Allgemeinen würde ich von diesem Ansatz abraten und stattdessen Folgendes empfehlen:
newdict = {**dict1, **dict2}
Der Ansatz des Auspackens ist klarer (für jeden, der das allgemeine Auspacken überhaupt kennt), die Sie ), erfordert überhaupt keinen Namen für das Ergebnis (daher ist es viel prägnanter, wenn ein temporäres Ergebnis konstruiert wird, das sofort an eine Funktion übergeben oder in eine list
/ tuple
Literal oder ähnliches), und ist mit ziemlicher Sicherheit auch schneller, da es (auf CPython) ungefähr gleichwertig ist:
newdict = {}
newdict.update(dict1)
newdict.update(dict2)
aber in der C-Schicht, unter Verwendung des Betons dict
API, so dass kein dynamischer Aufwand für Methodensuche/-bindung oder Funktionsaufrufe anfällt (wo (newdict := dict1.copy()).update(dict2)
ist vom Verhalten her zwangsläufig identisch mit dem ursprünglichen Zweizeiler und führt die Arbeit in diskreten Schritten aus, mit dynamischem Nachschlagen/Binden/Aufrufen von Methoden.
Es ist auch besser erweiterbar, da die Zusammenführung von drei dict
s ist offensichtlich:
newdict = {**dict1, **dict2, **dict3}
wo die Verwendung von Zuweisungsausdrücken nicht so skalieren würde; am ehesten könnte man das so machen:
(newdict := dict1.copy()).update(dict2), newdict.update(dict3)
oder ohne das temporäre Tupel von None
s, aber mit Wahrheitsgehaltstests für jede None
Ergebnis:
(newdict := dict1.copy()).update(dict2) or newdict.update(dict3)
Beide Varianten sind natürlich viel hässlicher und bringen weitere Ineffizienzen mit sich (entweder eine vergeudete vorübergehende tuple
de None
s für die Komma-Trennung oder sinnlose Wahrheits-Tests der einzelnen update
's None
Rückgabe für or
Trennung).
Der einzige wirkliche Vorteil des Zuweisungsausdrucks tritt auf, wenn:
- Sie haben generischen Code, der beides behandeln muss
set
s und dict
s (beide unterstützen copy
y update
so dass der Code ungefähr so funktioniert, wie man es erwarten würde)
- Sie erwarten, dass Sie beliebige diktatähnliche Objekte erhalten , nicht nur
dict
selbst, und muss den Typ und die Semantik der linken Seite beibehalten (anstatt mit einer einfachen dict
). Während myspecialdict({**speciala, **specialb})
funktionieren könnte, würde dies eine zusätzliche vorübergehende dict
, und wenn myspecialdict
hat einfache Merkmale dict
nicht bewahren kann (z. B. reguläre dict
s jetzt die Reihenfolge auf der Grundlage des ersten Auftretens eines Schlüssels und den Wert auf der Grundlage des letzten Auftretens eines Schlüssels beibehalten; Sie möchten vielleicht eine, die die Reihenfolge auf der Grundlage der zuletzt eines Schlüssels, so dass die Aktualisierung eines Wertes diesen auch an das Ende verschiebt), dann wäre die Semantik falsch. Da die Version des Zuweisungsausdrucks die benannten Methoden verwendet (die vermutlich überladen sind, um sich angemessen zu verhalten), wird niemals ein dict
überhaupt nicht (es sei denn dict1
war bereits ein dict
), wobei der ursprüngliche Typ (und die Semantik des ursprünglichen Typs) beibehalten wird, während alle temporären Elemente vermieden werden.