7080 Stimmen

Wie führe ich zwei Wörterbücher in einem einzigen Ausdruck zusammen (Vereinigung von Wörterbüchern)?

Ich möchte zwei Wörterbücher zu einem neuen Wörterbuch zusammenführen.

x = {'a': 1, 'b': 2}
y = {'b': 10, 'c': 11}

z = merge(x, y)

>>> z
{'a': 1, 'b': 10, 'c': 11}

使用方法 x.update(y) modifiziert x anstelle eines neuen Wörterbuchs zu erstellen. Ich möchte auch, dass die Konfliktbehandlung des letzten Gewinners von dict.update() auch.

19voto

kjo Punkte 30291

(Nur für Python2.7*; für Python3* gibt es einfachere Lösungen).

Wenn Sie nicht abgeneigt sind, ein Modul der Standardbibliothek zu importieren, können Sie

from functools import reduce

def merge_dicts(*dicts):
    return reduce(lambda a, d: a.update(d) or a, dicts, {})

(Die or a Bit im lambda ist notwendig, weil dict.update gibt immer zurück None bei Erfolg).

17voto

reetesh11 Punkte 603
from collections import Counter
dict1 = {'a':1, 'b': 2}
dict2 = {'b':10, 'c': 11}
result = dict(Counter(dict1) + Counter(dict2))

Damit sollte Ihr Problem gelöst sein.

0 Stimmen

Ich empfehle die Verwendung des Counter's .update() 代わりに + . Denn wenn die Summe für einen der Schlüssel den Wert 0 ergibt, wird dieser von Counter gelöscht.

17voto

upandacross Punkte 417

Das Problem, das ich mit den bisher aufgelisteten Lösungen habe, ist, dass im zusammengeführten Wörterbuch der Wert für den Schlüssel "b" 10 ist, aber meiner Meinung nach 12 sein sollte. Vor diesem Hintergrund schlage ich Folgendes vor:

import timeit

n=100000
su = """
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
"""

def timeMerge(f,su,niter):
    print "{:4f} sec for: {:30s}".format(timeit.Timer(f,setup=su).timeit(n),f)

timeMerge("dict(x, **y)",su,n)
timeMerge("x.update(y)",su,n)
timeMerge("dict(x.items() + y.items())",su,n)
timeMerge("for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k] ",su,n)

#confirm for loop adds b entries together
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k]
print "confirm b elements are added:",x

Ergebnisse:

0.049465 sec for: dict(x, **y)
0.033729 sec for: x.update(y)                   
0.150380 sec for: dict(x.items() + y.items())   
0.083120 sec for: for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k]

confirm b elements are added: {'a': 1, 'c': 11, 'b': 12}

1 Stimmen

Das könnte Sie interessieren cytoolz.merge_with ( toolz.readthedocs.io/de/latest/ )

17voto

GetFree Punkte 36514

Es ist so dumm, dass .update gibt nichts zurück.
Ich verwende nur eine einfache Hilfsfunktion, um das Problem zu lösen:

def merge(dict1,*dicts):
    for dict2 in dicts:
        dict1.update(dict2)
    return dict1

Beispiele:

merge(dict1,dict2)
merge(dict1,dict2,dict3)
merge(dict1,dict2,dict3,dict4)
merge({},dict1,dict2)  # this one returns a new copy

14voto

RemcoGerlich Punkte 28726

Dies kann mit einem einzigen Diktatverständnis geschehen:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> { key: y[key] if key in y else x[key]
      for key in set(x) + set(y)
    }

Meines Erachtens ist dies die beste Lösung für den Teil "Einfacher Ausdruck", da keine zusätzlichen Funktionen erforderlich sind und sie kurz ist.

0 Stimmen

Ich vermute, Leistung wird nicht sehr gut sein, obwohl; Erstellen eines Satzes aus jedem Diktat dann nur Iteration durch die Schlüssel bedeutet eine weitere Suche für den Wert jedes Mal (obwohl relativ schnell, noch erhöht die Reihenfolge der Funktion für Skalierung)

3 Stimmen

Das hängt von der Python-Version ab, die wir verwenden. In 3.5 und höher ergibt {**x,**y} das verkettete Wörterbuch

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X