2012-03-22 18 views
56

¿Cómo se calcula la unión de dos dict objetos en Python, donde un par (key, value) está presente en el resultado si y sólo si es keyin ya sea dict (a menos que existan duplicados)?Unión de objetos de diccionario en Python

Por ejemplo, la unión de {'a' : 0, 'b' : 1} y {'c' : 2} es {'a' : 0, 'b' : 1, 'c' : 2}.

Preferiblemente puede hacer esto sin modificar cualquiera de las entradas dict. Ejemplo de dónde esto es útil: Get a dict of all variables currently in scope and their values

+2

¿De qué manera esta pregunta es diferente a la que usted estableció en su propia respuesta? –

+1

@RikPoggi: La otra pregunta, a pesar de su título, es preguntar sobre qué es la sintaxis '** d2' *. Resulta proporcionar una respuesta a esta pregunta. –

Respuesta

55

This question proporciona una expresión idiomática. Se utiliza uno de los dicts como argumentos de palabra clave a la dict() constructor:

dict(y, **x) 

duplicados se resuelven a favor del valor de x; por ejemplo

dict({'a' : 'y[a]'}, **{'a', 'x[a]'}) == {'a' : 'x[a]'} 
+6

"Simple es mejor que complejo". :) Debes usar la función miembro 'update' de' dict'. – shahjapan

+12

¿Cómo es 'tmp = dict (y); tmp.update (x); do_something (tmp) 'simple? –

+6

@shahjapan Esto no es complejo, este es un gran uso de la estructura dict de Python. Y esto es diferente de la actualización (esta solución no actualiza nada). – lajarre

53

También puede utilizar update método de dict como

a = {'a' : 0, 'b' : 1} 
b = {'c' : 2} 

a.update(b) 
print a 
5

Si necesita ambos predice seguir siendo independiente, y actualizable, puede crear un único objeto que consulta los dos diccionarios en su __getitem__ método (e implemente get, __contains__ y otro método de mapeo cuando los necesite).

Un ejemplo minimalista podría ser así:

class UDict(object): 
    def __init__(self, d1, d2): 
     self.d1, self.d2 = d1, d2 
    def __getitem__(self, item): 
     if item in self.d1: 
      return self.d1[item] 
     return self.d2[item] 

Y funciona:

>>> a = UDict({1:1}, {2:2}) 
>>> a[2] 
2 
>>> a[1] 
1 
>>> a[3] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 7, in __getitem__ 
KeyError: 3 
>>> 
18

dos diccionarios

def union2(dict1, dict2): 
    return dict(list(dict1.items()) + list(dict2.items())) 

n Diccionarios

def union(*dicts): 
    return dict(itertools.chain.from_iterable(dct.items() for dct in dicts)) 
+12

O mucho más legible, 'dict (i para dct en dicts para i en dct.items())' – Eric

+0

¿Por qué convertir a list()? 'def union2 (dict1, dict2):' 'return dict (dict1.items() + dict2.items())' – kinORnirvana

+1

@kinORnirvana En python 3: a = {'x': 1}; tipo (a.items()) =>