views:

681

answers:

3

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

+5  A: 
d4 = dict(d1.items() + d2.items() + d3.items())

alternatively (and supposedly faster):

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

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

Amber
Instead of `d4 = dict(d1)` one could use `d4 = copy(d1)`.
Georg
@ds: That appears not to work. Perhaps you meant `from copy import copy; d4 = copy(d1)` or perhaps `d4 = d1.copy()`.
John Machin
+2  A: 

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)
sth
+4  A: 
  1. slowest: 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).

Alex Martelli
I don't understand why `d4 = dict(d1, **dict(d2, **d3))` isn't faster than #2, but it isn't.
Robert Rossney