values dictionaries dict concatenate python dictionary merge

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]}