2012-01-19 21 views
197

Tengo dos diccionarios existentes, y deseo 'adjuntar' uno de ellos al otro. Con eso quiero decir que la clave, los valores del otro diccionario deberían convertirse en el primer diccionario. Por ejemplo:¿Agregar diccionario a un diccionario?

orig = { 
    'A': 1, 
    'B': 2, 
    'C': 3, 
} 

extra = { 
    'D': 4, 
    'E': 5, 
} 

dest = # something here involving orig and extra 

print dest 
{ 
    'A': 1, 
    'B': 2, 
    'C': 3, 
    'D': 4, 
    'E': 5 
} 

Creo que todo esto se puede lograr a través de un bucle de for (tal vez?), Pero ¿hay algún método de diccionarios o cualquier otro módulo que guarda este trabajo para mí? Los diccionarios reales que estoy usando son muy grandes ...

+15

Algunas respuestas señalan 'orig.update (extra)' hace el trabajo. Tenga en cuenta que si 'extra' y' orig' tienen teclas superpuestas, el valor final se tomará de 'extra'. Por ejemplo, 'd1 = {1: 1, 2: 2}; d2 = {2: 'ha!', 3: 3}; d1.update (d2) 'dará como resultado' d1' que contiene '{1: 1, 2: 'ha!', 3: 3}'. –

Respuesta

310

Usted puede hacer

orig.update(extra) 

o, si usted no quiere orig a modificar, hacer una copia de primera:

dest = dict(orig) # or orig.copy() 
dest.update(extra) 

Tenga en cuenta que si adicional y orig tener llaves superpuestas , el valor final se tomará de extra. Por ejemplo,

>>> d1 = {1: 1, 2: 2} 
>>> d2 = {2: 'ha!', 3: 3} 
>>> d1.update(d2) 
>>> d1 
{1: 1, 2: 'ha!', 3: 3} 
+2

Hay dict.copy(), que hace copias superficiales como su método de copia. – sleeplessnerd

+0

He visto ese idiomático dict (** orig) antes. ¿Cuál es la ventaja sobre dict (orig)? – DSM

+2

El uso de 'dict (** orig)' creará un nuevo dict temporal que se utiliza como argumento de palabra clave para el constructor dict. El constructor copiará los valores de este argumento en sí mismo. Entonces usted crea un diccionario adicional con 'dict (** orig)'. Esto es un desperdicio cuando los diccionarios son grandes, como en la pregunta original. –

12

dict.update() parece que va a hacer lo que quiera ...

>> orig.update(extra) 
>>> orig 
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4} 
>>> 

Tal vez, sin embargo, que no quieren actualizar su diccionario originales , pero trabajar en una copia:

>>> dest = orig.copy() 
>>> dest.update(extra) 
>>> orig 
{'A': 1, 'C': 3, 'B': 2} 
>>> dest 
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4} 
5

No es el método .Update() :)

actualización ([otro]) Actualice el diccionario con los pares clave/valor de otro, sobrescribiendo las claves existentes. Devolver ninguno.

update() acepta ya sea otro objeto de diccionario o un iterable de pares clave/valor (como tuplas u otros iterables de longitud dos). Si se especifican los argumentos de la palabra clave , el diccionario se actualiza con esos pares clave/valor: d.update (rojo = 1, azul = 2).

Modificado en la versión 2.4: Permitido que el argumento sea un iterable de pares clave/valor y argumentos permitidos de palabra clave.

20

Suponiendo que usted no desea cambiar orig, puede hacer una copia y actualización al igual que las otras respuestas, o puede crear un nuevo diccionario en un solo paso por paso todos los artículos en ambos diccionarios al constructor dict:

from itertools import chain 
dest = dict(chain(orig.items(), extra.items())) 

o sin itertools:

dest = dict(list(orig.items()) + list(extra.items())) 

Tenga en cuenta que sólo tiene que pasar el resultado de items() en list() en Python 3, en 2.x dict.items() ya devuelve una lista por lo que puede hacer dict(orig.items() + extra.items()).

Como un caso de uso más general, supongamos que tiene una lista grande de predice que desea combinar en una sola dict, se podría hacer algo como esto:

from itertools import chain 
dest = dict(chain.from_iterable(map(dict.items, list_of_dicts))) 
+1

En realidad, prefiero este ya que puede "actualizar" un diccionario en la misma expresión que desea usar como parámetro, como: 'SomeClass (** dict (args.items() + {'special': a_value,}.items())) ' – carlosayam

5

La respuesta que quiero dar es "utilizar collections.ChainMap", pero acabo de descubrir que sólo se añadió en Python 3.3: https://docs.python.org/3.3/library/collections.html#chainmap-objects

Usted puede tratar de cuna de la clase de la fuente 3.3 embargo: http://hg.python.org/cpython/file/3.3/Lib/collections/init.py#l763

Aquí es una característica de menos de pleno Python 2.x compatib le versión (mismo autor): http://code.activestate.com/recipes/305268-chained-map-lookups/

En lugar de expandir/sobrescribir un diccionario con otro utilizando dict.merge, o crear una copia adicional fusionando ambos, crea una cadena de búsqueda que busca ambos en orden. Debido a que no duplica las asignaciones que envuelve, ChainMap usa muy poca memoria y ve modificaciones posteriores a cualquier submapeo. Como también importa el orden, también puede usar los valores predeterminados de la cadena a la capa (es decir, preferencias del usuario> config> env).

17

La forma más Pythonic (y un poco más rápido) para lograr esto es a través de:

dest = {**orig, **extra} 

O, dependiendo del problema a resolver, tal vez:

dest = {**orig, 'D': 4, 'E': 5} 
+2

lamentablemente no funciona para 2.x (((solo para 3.x – madjardi

+1

dict (itertools.chain (d.items(), y.items())) – madjardi

+0

Ambas versiones solo me dan una error de sintaxis en 3.x IDLE. – Noumenon

0

A tres forro de combinar o fusionar dos diccionarios:

dest = {} 
dest.update(orig) 
dest.update(extra) 

Esto crea un nuevo diccionario dest witho ut que modifica orig y extra.

Nota: Si una clave tiene valores diferentes en orig y extra, entonces extra prevalece sobre orig.

+0

Funciona tanto en Python 2 como en Python 3. – jkdev

Cuestiones relacionadas