369

Say I have three dicts

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

How do I create a new d4 that combines these three dictionaries? i.e.:

d4={1:2,3:4,5:6,7:9,10:8,13:22}
1
  • 41
    d4 = {**d1, **d2, **d3} --> {1: 2, 3: 4, 5: 6, 7: 9, 10: 8, 13: 22}
    – mujad
    Commented May 23, 2020 at 10:51

5 Answers 5

361
  1. Slowest and doesn't work in Python3: concatenate the items and call dict on the resulting list:

    $ 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. Fastest: exploit the dict constructor to the hilt, then one 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: a loop of update calls on an initially-empty dict:

    $ 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. Or, equivalently, one copy-ctor and two updates:

    $ 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
    

I recommend approach (2), and I particularly recommend avoiding (1) (which also takes up O(N) extra auxiliary memory for the concatenated list of items temporary data structure).

14
  • 12
    I don't understand why d4 = dict(d1, **dict(d2, **d3)) isn't faster than #2, but it isn't. Commented Nov 23, 2009 at 18:29
  • 15
    1 above is best if working on small dicts as it is clearer in my opinion.
    – Baz
    Commented Feb 28, 2012 at 20:13
  • 48
    Unless all keys are known to be strings, option 2 is an abuse of a Python 2 implementation detail (the fact that some builtins implemented in C bypassed the expected checks on keyword arguments). In Python 3 (and in PyPy), option 2 will fail with non-string keys.
    – Carl Meyer
    Commented Mar 30, 2013 at 23:09
  • 19
    I would add that d1.items() + d2.items() doesn't works in Python 3.
    – Francisco
    Commented Jan 10, 2017 at 17:00
  • 43
    In Python 3.5+ one can use the ** notation: d1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}; d4 = {**d1, **d2, **d3}, which for me was nearly 3x faster than #3 or #4 above (0.228 usec per loop vs. 0.661 or 0.595 usec for #3 or 4, respectively). As mentioned above, #1 and #2 don't work on Python 3.
    – jared
    Commented Apr 12, 2018 at 4:14
206

In python 2:

d4 = dict(d1.items() + d2.items() + d3.items())

In python 3 (and supposedly faster):

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

The previous SO question that both of these answers came from is here.

5
  • Instead of d4 = dict(d1) one could use d4 = copy(d1). Commented Nov 23, 2009 at 7:49
  • 1
    @ds: That appears not to work. Perhaps you meant from copy import copy; d4 = copy(d1) or perhaps d4 = d1.copy(). Commented Nov 23, 2009 at 9:05
  • 45
    First version doesn't work on Python3.
    – Superbest
    Commented Feb 6, 2015 at 3:37
  • 1
    Maybe d4 = d1.copy() Commented Oct 16, 2015 at 19:15
  • 2
    It does work in Python 3, but you have to cast the dict_items objects to real list objects. This is another case where Python 3 prioritised minor performance optimisations over simplicity and ease of use.
    – Carl Smith
    Commented Apr 12, 2017 at 13:26
106

You can use the update() method to build a new dictionary containing all the items:

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

Or, in a loop:

dall = {}
for d in [d1, d2, d3]:
  dall.update(d)
4
  • 5
    update does not build a new dictionary. It (as expected) updates the original one. Commented Feb 6, 2013 at 17:30
  • 10
    @A.J.Rouvoet: "The original one" in this case is a brand new empty dictionary in dall. This new dictionary gets repeatedly updated to contain all the elements. It's intentional that dall is changed.
    – sth
    Commented Feb 6, 2013 at 17:38
  • 2
    Ah, my comment was purely on the way you phrased the first sentence. It suggested something that isn't the case. Although I admit a down vote may have been a bit harsh. Commented Feb 6, 2013 at 22:09
  • logically using update we can create new dictionary by updating other and if we do not need the previous dic we can delete them using del d1 in for loop .
    – Jay
    Commented Oct 29, 2017 at 16:16
51

Here's a one-liner (imports don't count :) that can easily be generalized to concatenate N dictionaries:

Python 3

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

and:

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

Python 2.6 & 2.7

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

Output:

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

Generalized to concatenate N dicts:

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

I'm a little late to this party, I know, but I hope this helps someone.

5
  • 4
    imports do count. but the solution here is still interesting Commented Jun 18, 2017 at 16:18
  • for python 3.6 it should be d.items() instead of d.iteritems(). thanks for your contribution! Commented Jan 4, 2018 at 20:30
  • Just a detail for perfectionists, first version for Python3 is missing a closing parenthesis. Commented Apr 16, 2018 at 9:04
  • @sandroscodelller Thanks! Fixed. Commented Apr 16, 2018 at 12:46
  • I don't understand why Python hasn't implemented "+" operator for this common dictionary concatenation.
    – Shaun Han
    Commented Jun 8, 2021 at 17:03
34

Use the dict constructor

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

As a function

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

The overhead of creating intermediate dictionaries can be eliminated by using thedict.update() method:

from functools import reduce
def update(d, other): d.update(other); return d
d4 = reduce(update, (d1, d2, d3), {})
1
  • 1
    Does not work in Python3 as the kwargs have to have string keys
    – scravy
    Commented Dec 21, 2022 at 8:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.