Append a dictionary to a dictionary [duplicate]

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

1

7 Answers

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

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 

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.

2

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} 

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

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.

1

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.

The answer I want to give is "use collections.ChainMap", but I just discovered that it was only added in Python 3.3:

You can try to crib the class from the 3.3 source though: init.py#l763

Here is a less feature-full Python 2.x compatible version (same author):

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

You Might Also Like