How can I merge two dictionaries in a single expression in Python?

I want to merge two dictionaries into a new dictionary, so if a key is present in both dictionaries, only the value from the second dictionary should be kept.

x = {‘a’: 1, ‘b’: 2} y = {‘b’: 3, ‘c’: 4} z = merge(x, y)

Expected output:

z = {‘a’: 1, ‘b’: 3, ‘c’: 4}

To merge two dictionaries in Python into a new dictionary, keeping only the values from the second dictionary if a key is present in both, you can use the following methods:

For Python 3.9.0 or greater (released 17 October 2020, PEP-584):

z = x | y

For Python 3.5 or greater:

z = {**x, **y}

For Python 2, (or 3.4 or lower), you can use a function like this:

def merge_two_dicts(x, y):
    z = x.copy()   # start with keys and values of x
    z.update(y)    # modifies z with keys and values of y
    return z

Then, use the function to merge the dictionaries:

z = merge_two_dicts(x, y)

These methods will create a new dictionary z with the merged values, where the values from the second dictionary y overwrite those from the first dictionary x if a key is present in both dictionaries.

Another concise option for merging dictionaries in Python is:

z = dict(x, **y)

However, it’s important to note that this approach has some caveats. If the dictionary y has any non-string keys, using dict(x, **y) is an abuse of a CPython implementation detail and is not guaranteed to work in other Python implementations such as PyPy, IronPython, or Jython.

Additionally, this technique does not work in Python 3. Guido van Rossum, the creator of Python, has expressed dislike for this approach, stating that it is not Pythonic. Therefore, it’s recommended to avoid using this technique for forward-compatible or cross-implementation portable code.

In a follow-up answer, you inquired about the performance comparison between two alternatives for merging dictionaries in Python. Let’s explore this further:

  1. Concatenation Approach (z1):

    z1 = dict(x.items() + y.items())
    
  2. Keyword Argument Unpacking Approach (z2):

    z2 = dict(x, **y)
    

On a typical machine running Python 2.5.2, the keyword argument unpacking approach (z2) is not only shorter and simpler but also significantly faster than the concatenation approach (z1). You can verify this using the timeit module that comes with Python.

Example 1: For identical dictionaries mapping 20 consecutive integers to themselves:

% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z1=dict(x.items() + y.items())'
100000 loops, best of 3: 5.67 usec per loop
% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z2=dict(x, **y)' 
100000 loops, best of 3: 1.53 usec per loop

Here, z2 wins by a factor of approximately 3.5.

Example 2: For non-overlapping dictionaries mapping 252 short strings to integers and vice versa:

% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z1=dict(x.items() + y.items())'
1000 loops, best of 3: 260 usec per loop
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z2=dict(x, **y)'               
10000 loops, best of 3: 26.9 usec per loop

In this case, z2 wins by about a factor of 10.

Considering the poor performance of z1, which may be attributed to the overhead of constructing the two item lists, an alternative approach using itertools.chain was explored:

from itertools import chain
z3 = dict(chain(x.iteritems(), y.iteritems()))

Although z3 was found to be faster than z1 in some cases, it was not as fast as z2 and involved more typing, making it less preferable.

Finally, a performance comparison was made with the update method:

z0 = dict(x)
z0.update(y)

This approach (z0) showed essentially identical performance to z2, indicating that it’s impossible for pure Python code to perform significantly better than this. Both approaches provide a clean and efficient way to merge dictionaries, with z0 being particularly easy to understand and implement.