Cómo fusionar dos diccionarios en Python 2 y 3

Jinku Hu 30 enero 2023
  1. Fusión de diccionarios en Python 2.7
  2. Método de fusión del diccionario de Python 3.5 (y superior)
  3. Fusión de métodos Conclusión
Cómo fusionar dos diccionarios en Python 2 y 3

Supongamos que tenemos dos diccionarios A y B para ser fusionados, donde los valores en B reemplazarán a los valores en A si comparten la misma clave.

A = {"x": 10, "y": 20}
B = {"y": 30, "z": 40}

El objeto dictionary de Python tiene un método instrínseco update() para actualizar el diccionario A con el B,

A.update(B)

Pero los datos de A serán reemplazados en el lugar en lugar de devolver un nuevo diccionario que contenga la fusión de A y B.

Introduciremos los métodos de cómo fusionar dos diccionarios y devolver un nuevo diccionario.

Fusión de diccionarios en Python 2.7

Método de comprensión del diccionario - 1

C = {key: value for d in (A, B) for key, value in d.items()}

d.itmes() devuelve una lista de pares (clave, valor) como 2-tuplas del diccionario d.

Este método usa el anidado de comprensión de diccionario para fusionar dos diccionarios. Se debe prestar especial atención al orden correcto de for. Debería serlo,

flattern_patterns = [planet for sublist in planets for planet in sublist]

Método de comprensión del diccionario - 2

También podríamos usar el método dict() para inicializar el nuevo diccionario.

C = dict((key, value) for d in (A, B) for key, value in d.items())

Técnicamente hablando, es casi igual que el método anterior pero difiere en el rendimiento que se mencionará más adelante.

Método itertools.chain

El módulo herramientas estandariza un conjunto de bloques de construcción iterator. Tiene características como la rapidez y la eficiencia de la memoria.

itertools.chain devuelve un objeto chain cuyo método .next() devuelve elementos del primer iterable hasta que se agota, luego el/los siguiente(s) iterable(s), hasta que se agotan todos.

dict(itertools.chain(A.iteritems(), B.iteritems()))

iteritems() devuelve un iterador sobre los (key, value) elementos del diccionario.

Por lo tanto, los scripts anteriores devolverán un diccionario que contiene elementos de A y B.

Método copy y update

Como se mencionó al principio, update() podría fusionar A y B, pero reemplazará el diccionario que se encuentra en el lugar. Podríamos usar el método copy() para hacer una copia del diccionario A.

m = A.copy()
C = m.update(B)

Análisis y comparación del rendimiento de los métodos de fusión

import timeit

A = {"x": 10, "y": 20}
B = {"y": 30, "z": 40}

SETUP_CODE = """
A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
"""

TEST_CODE = """
{key: value for d in (A, B) for key, value in d.items()}
"""
print min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000))

TEST_CODE = """
dict((key, value) for d in (A, B) for key, value in d.items())
"""
print min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000))

TEST_CODE = """
dict(itertools.chain(A.iteritems(), B.iteritems()))
"""
print min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000))

SETUP_CODE = """
def merge_dicts(a, b):
    m = a.copy()
    m.update(b)
    return m

A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
"""

TEST_CODE = """
merge_dicts(A, B)
"""
print min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000))

El resultado es

0.0162378
0.029774
0.019975
0.0110059
Método Rendimiento Rango
{key: value for d in (A, B) for key, value in d.items()} 0.0162378 2
dict((key, value) for d in (A, B) for key, value in d.items()) 0.029774 4
dict(itertools.chain(A.iteritems(), B.iteritems())) 0.019975 3
merge_dicts(a, b) 0.0110059 1

Método de fusión del diccionario de Python 3.5 (y superior)

Desde Python 3.5, además de los mismos métodos que en Python 2.7, tiene también el operador de desempaquetado ** de dictionary, tal y como se introdujo en PEP-448. Permite desempaquetar un número arbitrario de elementos.

Atención
d.iteritems() se vuelve obsoleto en Python 3. Ver PEP-469
>>> C = {**A, **B}
>>> C
{'x': 10, 'y': 30, 'z': 40}
import timeit

A = {"x": 10, "y": 20}
B = {"y": 30, "z": 40}

SETUP_CODE = """
A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
"""

TEST_CODE = """
{**A, **B}
"""
print(min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000)))

TEST_CODE = """
{key: value for d in (A, B) for key, value in d.items()}
"""
print(min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000)))

TEST_CODE = """
dict((key, value) for d in (A, B) for key, value in d.items())
"""
print(min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000)))

TEST_CODE = """
dict(itertools.chain(A.items(), B.items()))
"""
print(min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000)))

SETUP_CODE = """
def merge_dicts(a, b):
    m = a.copy()
    m.update(b)
    return m

A = {'x': 10, 'y': 20}
B = {'y': 30, 'z': 40}
"""

TEST_CODE = """
merge_dicts(A, B)
"""
print(min(timeit.repeat(setup=SETUP_CODE, stmt=TEST_CODE, repeat=3, number=10000)))
0.0017047999999999508
0.009127499999999955
0.0168952
0.01078009999999996
0.005767999999999995
Método Rendimiento Rango
{**A, **B} 0.0017047999999999508 1
{key: value for d in (A, B) for key, value in d.items()} 0.009127499999999955 3
dict((key, value) for d in (A, B) for key, value in d.items()) 0.0168952 5
dict(itertools.chain(A.items(), B.items())) 0.01078009999999996 4
merge_dicts(a, b) 0.005767999999999995 2

Fusión de métodos Conclusión

En Python 2.7, copy y update es el mejor método.

m = A.copy()
C = m.update(B)

En Python 3.5+, el método de desempaquetado del diccionario es el mejor.

{**A, **B}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - Python Dictionary