{heroAlt}

How to Merge Two Dictionaries in Python: A Comprehensive Guide


Python’s dictionary is a powerhouse data structure, allowing you to store data in key-value pairs. As you work on more complex projects, a common task you’ll encounter is the need to merge two dictionaries into one. Whether you’re combining configuration settings, aggregating data from different sources, or simply updating a dataset, knowing how to do this efficiently is crucial. With Python’s consistent evolution, developers now have multiple ways to accomplish this, each with its own advantages.

This guide provides a straightforward, no-nonsense look at the most effective methods to merge two dictionaries in Python. We’ll cover everything from the classic update() method to the modern and elegant union operator, so you can choose the best tool for your specific situation. Python’s popularity continues to soar, consistently ranking among the top 3 languages in the TIOBE Index for years, partly due to its clear syntax and rich standard library that simplifies tasks like this.

The Classic: Using the update() Method

For a long time, the update() method was the standard way to merge one dictionary into another. This method modifies the original dictionary in-place, adding key-value pairs from the second dictionary.

How It Works

You call the update() method on the first dictionary and pass the second dictionary as an argument. The first dictionary is mutated directly.

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

dict1.update(dict2)
print(dict1)  # Output: {'a': 1, 'b': 3, 'c': 4}

Handling Key Collisions

As you can see in the example, if there’s a key collision (like the key 'b'), the value from the second dictionary (dict2) overwrites the value in the first one (dict1). This is a critical behavior to remember.

Pros:

  • Works in all relevant versions of Python.
  • Efficient for in-place updates when you don’t need to preserve the original dictionary.

Cons:

  • It modifies the original dictionary. If you need to keep the original intact, you must first create a copy.

To preserve dict1, you would do this:

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

merged_dict = dict1.copy()
merged_dict.update(dict2)
print(merged_dict)  # Output: {'a': 1, 'b': 3, 'c': 4}
print(dict1)      # Output: {'a': 1, 'b': 2}

The Modern Approach (Python 3.5+): Dictionary Unpacking with **

Introduced in Python 3.5 (PEP 448), the dictionary unpacking operator (**) provides a more readable and concise way to merge dictionaries. This method creates a new dictionary, leaving the original dictionaries untouched.

How It Works

You create a new dictionary and unpack the key-value pairs from the original dictionaries into it. The syntax is clean and intuitive.

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

merged_dict = {**dict1, **dict2}
print(merged_dict)  # Output: {'a': 1, 'b': 3, 'c': 4}

Handling Key Collisions

The unpacking operator handles collisions in a predictable way: the dictionary that is unpacked later takes precedence. In {**dict1, **dict2}, the values from dict2 will overwrite those from dict1 for any common keys.

Pros:

  • Creates a new dictionary, preserving the originals (immutable operation).
  • Highly readable and often considered more ‘Pythonic’.
  • Can be used to merge more than two dictionaries in one expression: {**dict1, **dict2, **dict3}.

Cons:

  • Only available in Python 3.5 and newer.

This method has become a favorite among developers for its clarity and safety, as it avoids accidental modification of the original data. In the age of big data where trillions of megabytes of data are processed daily, ensuring data integrity through immutable operations is a best practice (Forbes, 2023).

The Newest and Cleanest (Python 3.9+): The Union Operator |

Python 3.9 introduced a sleek new way to merge dictionaries: the union or merge operator (|). This syntax is even more concise than unpacking and is designed specifically for this task.

How It Works

Simply place the | operator between the two dictionaries you want to merge. This operation creates a new merged dictionary.

# This code requires Python 3.9+
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

merged_dict = dict1 | dict2
print(merged_dict)  # Output: {'a': 1, 'b': 3, 'c': 4}

In-Place Merging with |=

Python 3.9 also introduced the augmented assignment version, |=, which functions like update() by modifying a dictionary in-place.

# This code requires Python 3.9+
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

dict1 |= dict2
print(dict1)  # Output: {'a': 1, 'b': 3, 'c': 4}

Handling Key Collisions

Similar to the other methods, the right-hand operand’s values take precedence in case of a key collision.

Pros:

  • Extremely clean and readable syntax.
  • Clearly expresses the intent to merge two dictionaries.
  • Provides both a standard operator (|) for creating a new dictionary and an in-place operator (|=).

Cons:

  • It’s the newest method, so it requires Python 3.9 or later, which might not be available in older environments.

For Linked Views: collections.ChainMap

Sometimes, you don’t actually need to create a new, merged dictionary. Instead, you might want a combined view of several dictionaries, where lookups are performed sequentially across them. For this, Python’s standard library offers collections.ChainMap.

How It Works

ChainMap groups multiple dictionaries into a single, updatable view. The lookup process checks each dictionary in the order they are passed to the constructor. It doesn’t physically merge them, making it very fast to create.

from collections import ChainMap

default_config = {'theme': 'dark', 'font_size': 12}
user_config = {'font_size': 14, 'language': 'en'}

combined_config = ChainMap(user_config, default_config)

print(combined_config['font_size'])  # Output: 14 (from user_config)
print(combined_config['theme'])      # Output: 'dark' (from default_config)
print(combined_config['language'])   # Output: 'en' (from user_config)

Handling Key Collisions

ChainMap resolves key collisions by returning the value from the first dictionary in the chain that contains the key. In the example above, user_config is checked first, so its 'font_size' is used.

Pros:

  • Very fast to create as it doesn’t duplicate the underlying data.
  • Changes to the original dictionaries are reflected in the ChainMap.
  • Excellent for managing contexts or configuration settings with defaults.

Cons:

  • It is a view, not a new, independent dictionary. If you need a static, merged copy, you’ll need to convert it.

Choosing the Right Method: A Quick Guide

MethodPython VersionModifies Original?Use Case
d1.update(d2)AllYesIn-place modification is desired.
{**d1, **d2}3.5+NoCreating a new dictionary with clean, readable syntax.
`d1d2`3.9+No
`d1= d2`3.9+Yes
ChainMap(d1, d2)AllN/A (It’s a view)Creating a fast, logical view of multiple dicts without copying data.

Conclusion

Merging dictionaries is a fundamental operation in Python, and the language provides a rich set of tools to do it effectively. For modern Python development (3.9+), the union operator (|) is often the best choice for its clarity and purpose-built design. For slightly older but still modern codebases (3.5+), dictionary unpacking (**) is an excellent and widely-used alternative. The classic update() method remains relevant, especially when you intentionally want to modify a dictionary in-place. Finally, ChainMap offers a powerful, efficient solution for creating logical views instead of new objects.

Understanding these different techniques will allow you to write cleaner, more efficient, and more readable Python code. Now, go ahead and try these methods in your own projects to see which one best fits your workflow!