¿Existe alguna forma pitónica de combinar dos dictados (agregando valores para las claves que aparecen en ambos)?

Resuelto Derrick Zhang asked hace 12 años • 22 respuestas

Por ejemplo tengo dos dictados:

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

Necesito una forma pitónica de 'combinar' dos dictados de modo que el resultado sea:

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

Es decir: si una clave aparece en ambos dicts, suma sus valores, si aparece solo en un dict, mantiene su valor.

Derrick Zhang avatar Jun 13 '12 16:06 Derrick Zhang
Aceptado

Usar collections.Counter:

>>> from collections import Counter
>>> A = Counter({'a':1, 'b':2, 'c':3})
>>> B = Counter({'b':3, 'c':4, 'd':5})
>>> A + B
Counter({'c': 7, 'b': 5, 'd': 5, 'a': 1})

Los contadores son básicamente una subclase de dict, por lo que aún puedes hacer con ellos todo lo que normalmente harías con ese tipo, como iterar sobre sus claves y valores.

Martijn Pieters avatar Jun 13 '2012 09:06 Martijn Pieters

Una solución más genérica, que también funciona para valores no numéricos:

a = {'a': 'foo', 'b':'bar', 'c': 'baz'}
b = {'a': 'spam', 'c':'ham', 'x': 'blah'}

r = dict(a.items() + b.items() +
    [(k, a[k] + b[k]) for k in set(b) & set(a)])

o incluso más genérico:

def combine_dicts(a, b, op=operator.add):
    return dict(a.items() + b.items() +
        [(k, op(a[k], b[k])) for k in set(b) & set(a)])

Por ejemplo:

>>> a = {'a': 2, 'b':3, 'c':4}
>>> b = {'a': 5, 'c':6, 'x':7}

>>> import operator
>>> print combine_dicts(a, b, operator.mul)
{'a': 10, 'x': 7, 'c': 24, 'b': 3}
georg avatar Jun 13 '2012 09:06 georg