jerrymouse
Tengo que fusionar la lista del diccionario de python. Por ejemplo:
dicts[0] = {'a':1, 'b':2, 'c':3}
dicts[1] = {'a':1, 'd':2, 'c':'foo'}
dicts[2] = {'e':57,'c':3}
super_dict = {'a':[1], 'b':[2], 'c':[3,'foo'], 'd':[2], 'e':[57]}
Escribí el siguiente código:
super_dict = {}
for d in dicts:
for k, v in d.items():
if super_dict.get(k) is None:
super_dict[k] = []
if v not in super_dict.get(k):
super_dict[k].append(v)
¿Se puede presentar de forma más elegante/optimizada?
Nota
Encontré otra pregunta sobre SO, pero se trata de fusionar exactamente 2 diccionarios.
enviarle
Puede iterar sobre los diccionarios directamente, sin necesidad de usar range
. los setdefault
El método de dict busca una clave y devuelve el valor si lo encuentra. Si no se encuentra, devuelve un valor predeterminado y también asigna ese valor predeterminado a la clave.
super_dict = {}
for d in dicts:
for k, v in d.iteritems(): # d.items() in Python 3+
super_dict.setdefault(k, []).append(v)
Además, podría considerar el uso de un defaultdict
. Esto solo automatiza setdefault
llamando a una función para devolver un valor predeterminado cuando no se encuentra una clave.
import collections
super_dict = collections.defaultdict(list)
for d in dicts:
for k, v in d.iteritems(): # d.items() in Python 3+
super_dict[k].append(v)
Además, como observó astutamente Sven Marnach, parece que no desea duplicar valores en sus listas. En ese caso, set
te consigue lo que quieres:
import collections
super_dict = collections.defaultdict(set)
for d in dicts:
for k, v in d.iteritems(): # d.items() in Python 3+
super_dict[k].add(v)
-
O si está buscando una sola línea, esto podría ayudar: stackoverflow.com/a/45649266/6568097
– akhilsp
27 de enero de 2020 a las 14:29
Steven Rumbalski
from collections import defaultdict
dicts = [{'a':1, 'b':2, 'c':3},
{'a':1, 'd':2, 'c':'foo'},
{'e':57, 'c':3} ]
super_dict = defaultdict(set) # uses set to avoid duplicates
for d in dicts:
for k, v in d.items(): # use d.iteritems() in python 2
super_dict[k].add(v)
-
+1: Esto parece ser exactamente lo que pedía la pregunta (elementos únicos en los valores), hecho de una manera relativamente clara y ciertamente eficiente (los diccionarios se revisan una sola vez y el conjunto incorporado hace que solo se mantengan elementos únicos rápido).
– Eric O Lebigot
18 de mayo de 2013 a las 8:19
g_kuldeep
puedes usar este comportamiento de dict. (un poco elegante)
a = {'a':1, 'b':2, 'c':3}
b = {'d':1, 'e':2, 'f':3}
c = {1:1, 2:2, 3:3}
merge = {**a, **b, **c}
print(merge) # {'a': 1, 'b': 2, 'c': 3, 'd': 1, 'e': 2, 'f': 3, 1: 1, 2: 2, 3: 3}
y eres bueno para ir 🙂
-
Su solución reemplaza los valores de las claves, en lugar de combinarlos en una lista. Este es el resultado de tu solución:
{'a': 1, 'b': 2, 'c': 3, 'd': 2, 'e': 57}
– TitanFighter
24 sep 2019 a las 18:03
-
En mi caso, las claves eran únicas en cada dictado y esto era exactamente lo que quería. ¡Gracias!
– akhilsp
27 de enero de 2020 a las 14:33
-
este método elimina elementos duplicados en el diccionario.
– Shah Vipul
18 de febrero de 2021 a las 7:49
-
Pero, ¿cómo se hace en genérico para un número desconocido de diccionarios?
– Ala M.
28 de mayo de 2021 a las 11:54
-
¿Hay alguna manera de hacer esto para una lista de diccionarios?
– Trineo
26 oct a las 19:34
Sven Marnach
Combine las claves de todos los dictados y, para cada clave, ensamble la lista de valores:
super_dict = {}
for k in set(k for d in dicts for k in d):
super_dict[k] = [d[k] for d in dicts if k in d]
La expresion set(k for d in dicts for k in d)
construye un conjunto de todas las claves únicas de todos los diccionarios. Para cada una de estas claves únicas, usamos la lista de comprensión [d[k] for d in dicts if k in d]
para construir la lista de valores de todos los dictados para esta clave.
Ya que solo pareces a uno el único valor de cada clave, es posible que desee utilizar conjuntos en su lugar:
super_dict = {}
for k in set(k for d in dicts for k in d):
super_dict[k] = set(d[k] for d in dicts if k in d)
Parece que la mayoría de las respuestas que usan comprensiones no son tan legibles. En caso de que alguna se pierda en el lío de las respuestas anteriores, esto podría ser útil (aunque extremadamente tarde …). Simplemente recorra los elementos de cada dict y colóquelos en uno separado.
super_dict = {key:val for d in dicts for key,val in d.items()}
-
El OP quería ambos
'c'
valores conservados:{'c':[3,'foo']}
.–Steven Rumbalski
21 de julio de 2016 a las 15:09
Ramkrishan Sahu
Cuando el valor de las claves está en la lista:
from collections import defaultdict
dicts = [{'a':[1], 'b':[2], 'c':[3]},
{'a':[11], 'd':[2], 'c':['foo']},
{'e':[57], 'c':[3], "a": [1]} ]
super_dict = defaultdict(list) # uses set to avoid duplicates
for d in dicts:
for k, v in d.items(): # use d.iteritems() in python 2
super_dict[k] = list(set(super_dict[k] + v))
combined_dict = {}
for elem in super_dict.keys():
combined_dict[elem] = super_dict[elem]
combined_dict
## output: {'a': [1, 11], 'b': [2], 'c': [3, 'foo'], 'd': [2], 'e': [57]}
-
El OP quería ambos
'c'
valores conservados:{'c':[3,'foo']}
.–Steven Rumbalski
21 de julio de 2016 a las 15:09
Ovejas
Tengo una solución muy fácil de usar sin ninguna importación. Yo uso el método dict.update(). Pero lamentablemente se sobrescribirá, si la misma clave aparece en más de un diccionario, entonces el valor del dict combinado más reciente aparecerá en la salida.
dict1 = {'Name': 'Zara', 'Age': 7}
dict2 = {'Sex': 'female' }
dict3 = {'Status': 'single', 'Age': 27}
dict4 = {'Occupation':'nurse', 'Wage': 3000}
def mergedict(*args):
output = {}
for arg in args:
output.update(arg)
return output
print(mergedict(dict1, dict2, dict3, dict4))
los producción Es esto:
{‘Nombre’: ‘Zara’, ‘Edad’: 27, ‘Sexo’: ‘femenino’, ‘Estado’: ‘soltero’, ‘Ocupación’: ‘enfermera’, ‘Salario’: 3000}
Ver también: combinar diccionario anidado
– drftymac
11 de diciembre de 2017 a las 21:03
Ver también: pregunta similar
– drftymac
11 de diciembre de 2017 a las 21:07