dictionaries - python merge dictionary values
¿Cómo combinar múltiples dicts con la misma clave? (8)
Tengo múltiples pares de dictados / pares clave-valor como este:
d1 = {key1: x1, key2: y1}
d2 = {key1: x2, key2: y2}
Quiero que el resultado sea un nuevo dict (de la manera más eficiente, si es posible):
d = {key1: (x1, x2), key2: (y1, y2)}
En realidad, quiero que el resultado d sea:
d = {key1: (x1.x1attrib, x2.x2attrib), key2: (y1.y1attrib, y2.y2attrib)}
Si alguien me muestra cómo obtener el primer resultado, puedo descubrir el resto.
Aquí hay un enfoque que puede usar que funcionaría incluso si ambos dictonarios no tienen las mismas claves:
d1 = {''a'':''test'',''b'':''btest'',''d'':''dreg''}
d2 = {''a'':''cool'',''b'':''main'',''c'':''clear''}
d = {}
for key in set(d1.keys() + d2.keys()):
try:
d.setdefault(key,[]).append(d1[key])
except KeyError:
pass
try:
d.setdefault(key,[]).append(d2[key])
except KeyError:
pass
print d
Esto generaría la entrada siguiente:
{''a'': [''test'', ''cool''], ''c'': [''clear''], ''b'': [''btest'', ''main''], ''d'': [''dreg'']}
Aquí hay una solución general que manejará una cantidad arbitraria de diccionarios, con casos en que las claves están en solo algunos de los diccionarios:
from collections import defaultdict
d1 = {1: 2, 3: 4}
d2 = {1: 6, 3: 7}
dd = defaultdict(list)
for d in (d1, d2): # you can list as many input dicts as you want here
for key, value in d.iteritems():
dd[key].append(value)
print(dd)
Muestra:
defaultdict(<type ''list''>, {1: [2, 6], 3: [4, 7]})
Además, para obtener su .attrib
, simplemente cambie append(value)
para append(value.attrib)
Si solo tiene d1 y d2,
from collections import defaultdict
d = defaultdict(list)
for a, b in d1.items() + d2.items():
d[a].append(b)
Una posibilidad compacta
d1={''a'':1,''b'':2}
d2={''c'':3,''d'':4}
context={**d1, **d2}
context
{''b'': 2, ''c'': 3, ''d'': 4, ''a'': 1}
asumiendo que todas las claves están siempre presentes en todos los dictados:
ds = [d1, d2]
d = {}
for k in d1.iterkeys():
d[k] = tuple(d[k] for d in ds)
Actualización de Python 3.x
De la respuesta de Eli Bendersky:
Python 3 eliminado dict.iteritems usa dict.items en su lugar. Ver el wiki de Python: https://wiki.python.org/moin/Python3.0
from collections import defaultdict
dd = defaultdict(list)
for d in (d1, d2):
for key, value in d.items():
dd[key].append(value)
def merge(d1, d2, merge):
result = dict(d1)
for k,v in d2.iteritems():
if k in result:
result[k] = merge(result[k], v)
else:
result[k] = v
return result
d1 = {''a'': 1, ''b'': 2}
d2 = {''a'': 1, ''b'': 3, ''c'': 2}
print merge(d1, d2, lambda x, y:(x,y))
{''a'': (1, 1), ''c'': 2, ''b'': (2, 3)}
dict1 = {''m'': 2, ''n'': 4}
dict2 = {''m'': 1, ''n'': 3}
{i:j for i in k.keys() for j in zip(dict1.values(),dict2.values())}
da:
{''m'': (3, 2), ''n'': (3, 2)}
si quieres la fusión en forma de lista:
{i:list(j) for i in k.keys() for j in zip(dict1.values(),dict2.values())}
da:
{''m'': [3, 2], ''n'': [3, 2]}