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.

2voto

Daniel Farrell Punkte 11558

Hier ist eine weitere Option, die Wörterbuchverständnisse in Kombination mit dem Verhalten von dict() :

dict3 = dict(dict1, **{ k: v + dict1.get(k, 0) for k, v in dict2.items() })
# {'a': 4, 'b': 2, 'c': 7, 'g': 1}

Von https://docs.python.org/3/library/stdtypes.html#dict :

https://docs.python.org/3/library/stdtypes.html#dict

und auch

Wenn Schlüsselwortargumente angegeben werden, werden die Schlüsselwortargumente und ihre Werte zu dem aus dem Positionsargument erstellten Wörterbuch hinzugefügt.

Das Diktat-Verständnis

**{ k: v + dict1.get(v, 0), v in dict2.items() }

behandelt das Hinzufügen von dict1[1] zu v . Wir brauchen keine explizite if hier, weil der Standardwert für unsere dict1.get kann stattdessen auf 0 gesetzt werden.

1voto

Lacobus Punkte 1540

Worüber?

def dict_merge_and_sum( d1, d2 ):
    ret = d1
    ret.update({ k:v + d2[k] for k,v in d1.items() if k in d2 })
    ret.update({ k:v for k,v in d2.items() if k not in d1 })
    return ret

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

print( dict_merge_and_sum( A, B ) )

Sortie :

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

1voto

Ignacio Villela Punkte 150

Diese Lösung ist einfach zu benutzen, sie wird wie ein normales Wörterbuch verwendet, aber Sie können die Summenfunktion benutzen.

class SumDict(dict):
    def __add__(self, y):
        return {x: self.get(x, 0) + y.get(x, 0) for x in set(self).union(y)}

A = SumDict({'a': 1, 'c': 2})
B = SumDict({'b': 3, 'c': 4})  # Also works: B = {'b': 3, 'c': 4}
print(A + B)  # OUTPUT {'a': 1, 'b': 3, 'c': 6}

0voto

A.Ranjan Punkte 119

Konventionellere Art, zwei Diktate zu kombinieren. Die Verwendung von Modulen und Werkzeugen ist gut, aber das Verständnis der Logik dahinter hilft, falls Sie sich nicht an die Werkzeuge erinnern können.

Programm zum Kombinieren zweier Wörterbücher durch Hinzufügen von Werten für gemeinsame Schlüssel.

def combine_dict(d1,d2):

for key,value in d1.items():
  if key in d2:
    d2[key] += value
  else:
      d2[key] = value
return d2

combine_dict({'a':1, 'b':2, 'c':3},{'b':3, 'c':4, 'd':5})

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

0voto

Yann Dubois Punkte 1019

Hier ist eine sehr allgemeine Lösung. Sie können mit einer beliebigen Anzahl von Diktaten und Schlüsseln umgehen, die nur in einigen Diktaten enthalten sind, und einfach jede beliebige Aggregationsfunktion verwenden, die Sie möchten:

def aggregate_dicts(dicts, operation=sum):
    """Aggregate a sequence of dictionaries using `operation`."""
    all_keys = set().union(*[el.keys() for el in dicts])
    return {k: operation([dic.get(k, None) for dic in dicts]) for k in all_keys}

Beispiel:

dicts_same_keys = [{'x': 0, 'y': 1}, {'x': 1, 'y': 2}, {'x': 2, 'y': 3}]
aggregate_dicts(dicts_same_keys, operation=sum)
#{'x': 3, 'y': 6}

Beispiel nicht-identische Schlüssel und generische Aggregation:

dicts_diff_keys = [{'x': 0, 'y': 1}, {'x': 1, 'y': 2}, {'x': 2, 'y': 3, 'c': 4}]

def mean_no_none(l):
    l_no_none = [el for el in l if el is not None]
    return sum(l_no_none) / len(l_no_none)

aggregate_dicts(dicts_diff_keys, operation=mean_no_none)
# {'x': 1.0, 'c': 4.0, 'y': 2.0}

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