Come fondere due dizionari in Python 2 e 3
- Dizionario Python 2.7 Merge
- Python 3.5 (e oltre) Dizionario Metodo di fusione del dizionario
- Conclusione sui metodi di fusione
Supponiamo di avere due dizionari A
e B
da fondere, dove i valori in B
sostituiranno i valori in A
se condividono la stessa chiave
.
A = {"x": 10, "y": 20}
B = {"y": 30, "z": 40}
L’oggetto dictionary
di Python ha un metodo instrinseco update()
metodo per aggiornare il dizionario A
con B
,
A.update(B)
Ma i dati di A
saranno sostituiti sul posto invece di restituire un nuovo dizionario contenente la fusione di A
e B
.
Introdurremo i metodi per fondere due dizionari e restituire un nuovo dizionario.
Dizionario Python 2.7 Merge
Metodo di comprensione del dizionario - 1
C = {key: value for d in (A, B) for key, value in d.items()}
d.itmes()
restituisce una lista di coppie (key, value)
come 2-tuple del dizionario d
.
Questo metodo usa il nested dictionary comprehension per unire due dizionari. Il giusto ordine di for
dovrebbe essere oggetto di una maggiore attenzione. Dovrebbe essere,
flattern_patterns = [planet for sublist in planets for planet in sublist]
Metodo di comprensione del dizionario - 2
Potremmo anche usare il metodo dict()
per inizializzare il nuovo dizionario.
C = dict((key, value) for d in (A, B) for key, value in d.items())
Tecnicamente parlando, è quasi uguale al metodo di cui sopra, ma si differenzia per le prestazioni che saranno menzionate in seguito.
Metodo itertools.chain
Il modulo itertools
standardizza un nucleo di blocchi di costruzione iterator
. Ha caratteristiche come la velocità e l’efficienza della memoria.
itertools.chain
restituisce un oggetto a catena il cui metodo .next()
restituisce elementi dal primo iterabile fino all’esaurimento, poi il/i successivo/i iterabile/i, fino all’esaurimento di tutti.
dict(itertools.chain(A.iteritems(), B.iteritems()))
iteritems()
restituisce un iteratore sopra gli elementi (chiave, valore)
del dizionario.
Pertanto, gli script sopra riportati restituiranno un dizionario contenente elementi di A e B.
Metodo copy
e update
Come detto all’inizio, update()
potrebbe fondere A
e B
, ma sostituirà il dizionario in-place. Potremmo usare il metodo copy()
per fare una copia del dizionario A
.
m = A.copy()
C = m.update(B)
Unire i metodi Analisi delle prestazioni e confronto
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))
Il risultato è
0.0162378
0.029774
0.019975
0.0110059
Metodo | Prestazioni | Classifica |
---|---|---|
{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 |
Python 3.5 (e oltre) Dizionario Metodo di fusione del dizionario
Da Python 3.5, oltre agli stessi metodi di Python 2.7, ha anche l’operatore di “disimballaggio” del “contraddittorio”, come introdotto in PEP-448. Esso permette di spacchettare un numero arbitrario di elementi.
d.iteritems()
diventa deprecato in Python 3. Vedere 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
Metodo | Prestazioni | Classifica |
---|---|---|
{**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 |
Conclusione sui metodi di fusione
In Python 2.7, copy
e update
è il metodo migliore.
m = A.copy()
C = m.update(B)
In Python 3.5+, il metodo di disimballaggio del dizionario è il migliore.
{**A, **B}
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