545 Stimmen

Gibt es eine pythonische Möglichkeit, zwei Dicts (Hinzufügen von Werten für Schlüssel, die in beiden erscheinen) zu kombinieren?

Ich habe zum Beispiel zwei Dicts:

Dict A: {'a': 1, 'b': 2, 'c': 3}
Dict B: {'b': 3, 'c': 4, 'd': 5}

Ich brauche einen pythonischen Weg der "Kombination" zwei Dicts, so dass das Ergebnis ist:

{'a': 1, 'b': 5, 'c': 7, 'd': 5}

Das heißt: Wenn ein Schlüssel in beiden Dicts vorkommt, addiere ihre Werte, wenn er nur in einem Dict vorkommt, behalte seinen Wert.

6voto

shouldsee Punkte 416

Bitte beachten Sie außerdem a.update( b ) ist 2x schneller als a + b

from collections import Counter
a = Counter({'menu': 20, 'good': 15, 'happy': 10, 'bar': 5})
b = Counter({'menu': 1, 'good': 1, 'bar': 3})

%timeit a + b;
## 100000 loops, best of 3: 8.62 µs per loop
## The slowest run took 4.04 times longer than the fastest. This could mean that an intermediate result is being cached.

%timeit a.update(b)
## 100000 loops, best of 3: 4.51 µs per loop

6voto

Buoy Rina Punkte 428

Eine Lösung ist die Verwendung des Wörterbuchverständnisses.

C = { k: A.get(k,0) + B.get(k,0) for k in list(B.keys()) + list(A.keys()) }

3voto

Jonas Kölker Punkte 7382
def merge_with(f, xs, ys):
    xs = a_copy_of(xs) # dict(xs), maybe generalizable?
    for (y, v) in ys.iteritems():
        xs[y] = v if y not in xs else f(xs[x], v)

merge_with((lambda x, y: x + y), A, B)

Das kann man leicht verallgemeinern:

def merge_dicts(f, *dicts):
    result = {}
    for d in dicts:
        for (k, v) in d.iteritems():
            result[k] = v if k not in result else f(result[k], v)

Dann kann sie eine beliebige Anzahl von Dicts aufnehmen.

3voto

ragardner Punkte 1644

Dies ist eine einfache Lösung für die Zusammenführung von zwei Wörterbüchern, bei denen += auf die Werte angewendet werden kann, muss es ein Wörterbuch nur einmal durchlaufen

a = {'a':1, 'b':2, 'c':3}

dicts = [{'b':3, 'c':4, 'd':5},
         {'c':9, 'a':9, 'd':9}]

def merge_dicts(merged,mergedfrom):
    for k,v in mergedfrom.items():
        if k in merged:
            merged[k] += v
        else:
            merged[k] = v
    return merged

for dct in dicts:
    a = merge_dicts(a,dct)
print (a)
#{'c': 16, 'b': 5, 'd': 14, 'a': 10}

2voto

Michael Hall Punkte 2093

Die oben genannten Lösungen eignen sich hervorragend für den Fall, dass Sie eine kleine Anzahl von Counter s. Wenn Sie jedoch eine große Liste von ihnen haben, ist so etwas viel schöner:

from collections import Counter

A = Counter({'a':1, 'b':2, 'c':3})
B = Counter({'b':3, 'c':4, 'd':5}) 
C = Counter({'a': 5, 'e':3})
list_of_counts = [A, B, C]

total = sum(list_of_counts, Counter())

print(total)
# Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3})

Die obige Lösung ist im Wesentlichen eine Summierung der Counter s von:

total = Counter()
for count in list_of_counts:
    total += count
print(total)
# Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3})

Dies tut dasselbe, aber ich denke, es ist immer hilfreich zu sehen, was es darunter tatsächlich tut.

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