web-dev-qa-db-fra.com

comment concaténer deux dictionnaires pour en créer un nouveau en Python?

Dis que j'ai trois dicts

d1={1:2,3:4}
d2={5:6,7:9}
d3={10:8,13:22}

Comment créer un nouveau d4 qui combine ces trois dictionnaires? c'est à dire.:

d4={1:2,3:4,5:6,7:9,10:8,13:22}
205
timy
  1. Le plus lent et ne fonctionne pas dans Python3: concaténez le items et appelez dict dans la liste résultante:

    $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
    'd4 = dict(d1.items() + d2.items() + d3.items())'
    
    100000 loops, best of 3: 4.93 usec per loop
    
  2. Le plus rapide: exploite le constructeur dict jusqu'au bout, puis un update:

    $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
    'd4 = dict(d1, **d2); d4.update(d3)'
    
    1000000 loops, best of 3: 1.88 usec per loop
    
  3. Middling: une boucle de update appelle un dict initialement vide:

    $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
    'd4 = {}' 'for d in (d1, d2, d3): d4.update(d)'
    
    100000 loops, best of 3: 2.67 usec per loop
    
  4. Ou, de manière équivalente, un copieur-copieur et deux mises à jour:

    $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
    'd4 = dict(d1)' 'for d in (d2, d3): d4.update(d)'
    
    100000 loops, best of 3: 2.65 usec per loop
    

Je recommande l'approche (2), et je recommande particulièrement d'éviter (1) (qui occupe également O(N) mémoire auxiliaire supplémentaire pour la structure concaténée d'éléments temporaires de données).

241
Alex Martelli
d4 = dict(d1.items() + d2.items() + d3.items())

alternativement (et soi-disant plus rapide):

d4 = dict(d1)
d4.update(d2)
d4.update(d3)

La précédente SO question à l'origine de ces deux réponses est ici .

105
Amber

Vous pouvez utiliser la méthode update() pour créer un nouveau dictionnaire contenant tous les éléments:

dall = {}
dall.update(d1)
dall.update(d2)
dall.update(d3)

Ou en boucle:

dall = {}
for d in [d1, d2, d3]:
  dall.update(d)
56
sth

Utilisez le constructeur dict

d1={1:2,3:4}
d2={5:6,7:9}
d3={10:8,13:22}

d4 = reduce(lambda x,y: dict(x, **y), (d1, d2, d3))

En tant que fonction

from functools import partial
dict_merge = partial(reduce, lambda a,b: dict(a, **b))

La surcharge de la création de dictionnaires intermédiaires peut être éliminée en utilisant la méthodedict.update():

from functools import reduce
def update(d, other): d.update(other); return d
d4 = reduce(update, (d1, d2, d3), {})
23

Voici un one-liner (imports ne compte pas :) qui peut facilement être généralisé pour concaténer N dictionnaires:

Python 2.6+

from itertools import chain
dict(chain.from_iterable(d.iteritems() for d in (d1, d2, d3))

Sortie:

>>> from itertools import chain
>>> d1={1:2,3:4}
>>> d2={5:6,7:9}
>>> d3={10:8,13:22}
>>> dict(chain.from_iterable(d.iteritems() for d in (d1, d2, d3)))
{1: 2, 3: 4, 5: 6, 7: 9, 10: 8, 13: 22}

Généralisé pour concaténer N dict:

from itertools import chain
def dict_union(*args):
    return dict(chain.from_iterable(d.iteritems() for d in args))

Python 3

from itertools import chain
dict(chain.from_iterable(d.items() for d in (d1, d2, d3)))

et:

from itertools import chain
def dict_union(*args):
    return dict(chain.from_iterable(d.items() for d in args))

Je sais que je suis un peu en retard à cette fête, mais j'espère que cela aidera quelqu'un.

22
ron rothman