551

I have two existing dictionaries, and I wish to 'append' one of them to the other. By that I mean that the key,values of the other dictionary should be made into the first dictionary. For example:

orig = {
   'A': 1,
   'B': 2,
   'C': 3,
}

extra = {
   'D': 4,
   'E': 5,
}

dest = # Something here involving orig and extra

print dest
{
   'A': 1,
   'B': 2,
   'C': 3,
   'D': 4,
   'E': 5
}

I think this all can be achieved through a for loop (maybe?), but is there some method of dictionaries or any other module that saves this job for me? The actual dictionaries I'm using are really big...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Javier Novoa C.
  • 11,257
  • 13
  • 57
  • 75
  • 29
    A few answers point out `orig.update(extra)` does the job. Do take note that if `extra` and `orig` have overlapping keys, the final value will be taken from `extra`. For example, `d1={1: 1, 2: 2}; d2={2: 'ha!', 3: 3}; d1.update(d2)` will result in `d1` containing `{1: 1, 2: 'ha!', 3: 3}`. – Steven Rumbalski Jan 19 '12 at 18:56

7 Answers7

771

You can do

orig.update(extra)

or, if you don't want orig to be modified, make a copy first:

dest = dict(orig)  # or orig.copy()
dest.update(extra)

Note that if extra and orig have overlapping keys, the final value will be taken from extra. For example,

>>> d1 = {1: 1, 2: 2}
>>> d2 = {2: 'ha!', 3: 3}
>>> d1.update(d2)
>>> d1
{1: 1, 2: 'ha!', 3: 3}
Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 4
    There is dict.copy(), which makes shallow copies like your copy method. – sleeplessnerd Jan 19 '12 at 18:00
  • 1
    I've seen that dict(**orig) idiom before. What's the advantage over dict(orig)? – DSM Jan 19 '12 at 18:00
  • 6
    Using `dict(**orig)` will create a new temporary dict that is used as keyword argument for the dict constructor. The constructor will then copy the values from this argument into itself. So you create an additional dictionary with `dict(**orig)`. This is wasteful when the dictionaries are big, as in the original question. – Martin Geisler Jan 19 '12 at 18:05
  • 1
    Though, I just ran a quick empirical test with `timeit` on the standard CPython (2.7), and `dict(**orig)` is **slightly** faster. YMMV, and it depends on your implementation--but I'm not entirely sure the `**` idiom in this case really does incur extra overhead in all implementations, perhaps because `dict` is a built-in type. – HardlyKnowEm Jan 19 '12 at 18:16
  • 16
    This breaks if your keys are not valid keyword arguments. E.g. `x = {1: 1}; dict(**x)` – Rob Wouters Jan 19 '12 at 18:40
  • it's agreed `dict(**orig)` is not so good - anyone have an opinion on `dict(orig)` vs `orig = dict.copy()` ? – Anentropic Aug 30 '13 at 16:16
  • if you do "orig.update(extra)" and a duplicate value is in the second dictionary, do you have to worry about the over-written values being shallow copies... for that matter, do you have to worry about only getting shallow copies at all? –  Jun 05 '16 at 01:06
  • Isn't `copy.deepcopy` better than `dict(**orig)`? It's simpler and clearer. – 0xc0de May 26 '18 at 19:50
183

There are two ways to add one dictionary to another:

Update (modifies orig in place)

orig.update(extra)    # Python 2.7+
orig |= extra         # Python 3.9+

Merge (creates a new dictionary)

# Python 2.7+
dest = collections.ChainMap(orig, extra)
dest = {k: v for d in (orig, extra) for (k, v) in d.items()}

# Python 3
dest = {**orig, **extra}          
dest = {**orig, 'D': 4, 'E': 5}

# Python 3.9+ 
dest = orig | extra

Caveats

Note that these operations are noncommutative. In all cases, the latter is the winner. E.g.

orig  = {'A': 1, 'B': 2}
extra = {'A': 3, 'C': 3}

dest = orig | extra
# dest = {'A': 3, 'B': 2, 'C': 3}

dest = extra | orig
# dest = {'A': 1, 'B': 2, 'C': 3}

It is also important to note that only from Python 3.7 (and CPython 3.6) dicts are ordered. So, in previous versions, the order of the items in the dictionary may vary.

Nuno André
  • 4,739
  • 1
  • 33
  • 46
33

dict.update() looks like it will do what you want...

>> orig.update(extra)
>>> orig
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4}
>>> 

Perhaps, though, you don't want to update your original dictionary, but work on a copy:

>>> dest = orig.copy()
>>> dest.update(extra)
>>> orig
{'A': 1, 'C': 3, 'B': 2}
>>> dest
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4}
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
29

Assuming that you do not want to change orig, you can either do a copy and update like the other answers, or you can create a new dictionary in one step by passing all items from both dictionaries into the dict constructor:

from itertools import chain
dest = dict(chain(orig.items(), extra.items()))

Or without itertools:

dest = dict(list(orig.items()) + list(extra.items()))

Note that you only need to pass the result of items() into list() on Python 3, on 2.x dict.items() already returns a list so you can just do dict(orig.items() + extra.items()).

As a more general use case, say you have a larger list of dicts that you want to combine into a single dict, you could do something like this:

from itertools import chain
dest = dict(chain.from_iterable(map(dict.items, list_of_dicts)))
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
  • 2
    Actually I prefer this one as you can 'update' a dictionary in the same expression you want to use it as parameter, like: `SomeClass(**dict(args.items()+{'special':a_value,}.items()))` – carlosayam Feb 04 '13 at 07:03
20

A three-liner to combine or merge two dictionaries:

dest = {}
dest.update(orig)
dest.update(extra)

This creates a new dictionary dest without modifying orig and extra.

Note: If a key has different values in orig and extra, then extra overrides orig.

jkdev
  • 11,360
  • 15
  • 54
  • 77
9

There is the .update() method :)

update([other]) Update the dictionary with the key/value pairs from other, overwriting existing keys. Return None.

update() accepts either another dictionary object or an iterable of key/value pairs (as tuples or other iterables of length two). If keyword arguments are specified, the dictionary is then updated with those key/value pairs: d.update(red=1, blue=2).

Changed in version 2.4: Allowed the argument to be an iterable of key/value pairs and allowed keyword arguments.

chepner
  • 497,756
  • 71
  • 530
  • 681
sleeplessnerd
  • 21,853
  • 1
  • 25
  • 29
8

The answer I want to give is "use collections.ChainMap", but I just discovered that it was only added in Python 3.3: https://docs.python.org/3.3/library/collections.html#chainmap-objects

You can try to crib the class from the 3.3 source though: http://hg.python.org/cpython/file/3.3/Lib/collections/init.py#l763

Here is a less feature-full Python 2.x compatible version (same author): http://code.activestate.com/recipes/305268-chained-map-lookups/

Instead of expanding/overwriting one dictionary with another using dict.merge, or creating an additional copy merging both, you create a lookup chain that searches both in order. Because it doesn't duplicate the mappings it wraps ChainMap uses very little memory, and sees later modifications to any sub-mapping. Because order matters you can also use the chain to layer defaults (i.e. user prefs > config > env).

kitsu.eb
  • 2,996
  • 1
  • 26
  • 28