Comment fusionner deux dictionnaires en Python 2 et 3

Jinku Hu 30 janvier 2023
  1. Fusion de dictionnaires Python 2.7
  2. Méthode de fusion de dictionnaire Python 3.5 (et plus)
  3. Conclusion sur les méthodes de fusion
Comment fusionner deux dictionnaires en Python 2 et 3

Supposons que nous ayons deux dictionnaires A et B à fusionner, où les valeurs dans B remplaceront les valeurs dans A si elles partagent la même key.

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

L’objet Python dictionnaire a une méthode instrinsèque update() pour mettre à jour le dictionnaire A avec B,

A.update(B)

Mais les données de A seront remplacées à la place au lieu de retourner un nouveau dictionnaire contenant la fusion de A et B.

Nous allons présenter les méthodes de fusion de deux dictionnaires et de retour d’un nouveau dictionnaire.

Fusion de dictionnaires Python 2.7

Méthode de compréhension du dictionnaire - 1

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

d.itmes() retourne une liste de paires (clé, valeur) comme 2-tuples du dictionnaire d.

Cette méthode utilise la compréhension des dictionnaires imbriqués pour fusionner deux dictionnaires. Le bon ordre de for doit être pris en compte. Il devrait l’être,

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

Méthode de compréhension du dictionnaire - 2

Nous pourrions aussi utiliser la méthode dict() pour initialiser le nouveau dictionnaire.

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

Techniquement parlant, elle est presque la même que la méthode ci-dessus mais diffère dans les performances qui seront mentionnées par la suite.

Méthode itertools.chain

Le module itertools standardise un ensemble de blocs de construction iterator. Il a des caractéristiques comme la rapidité et l’efficacité de la mémoire.

itertools.chain retourne un objet chaîne dont la méthode .next() retourne les éléments du premier itérable jusqu’à ce qu’il soit épuisé, puis le(s) itérable(s) suivant(s), jusqu’à ce que tous soient épuisés.

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

iteritems() retourne un itérateur sur les éléments (key, value) du dictionnaire.

Par conséquent, les scripts ci-dessus retourneront un dictionnaire contenant les éléments de A et B.

Méthode copy et update

Comme mentionné au début, update() pourrait fusionner A et B, mais remplacera le dictionnaire en place. Nous pourrions utiliser la méthode copy() pour faire une copie du dictionnaire A.

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

Fusionner les méthodes Analyse et comparaison des performances

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))

Le résultat est

0.0162378
0.029774
0.019975
0.0110059
Méthode Performance Classement
{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éthode de fusion de dictionnaire Python 3.5 (et plus)

A partir de Python 3.5, en plus des mêmes méthodes que dans Python 2.7, il a aussi l’opérateur de décompactage ** de dictionary, comme introduit dans PEP-448. Il permet de décompresser un nombre arbitraire d’éléments.

Attention
d.iteritems() devient obsolète en Python 3. Voir 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éthode Performance Classement
{**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

Conclusion sur les méthodes de fusion

En Python 2.7, copy et update est la meilleure méthode.

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

En Python 3.5+, la méthode de déballage du dictionnaire est la meilleure.

{**A, **B}
Auteur: 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

Article connexe - Python Dictionary