PythonMastery

How do I merge two dictionaries in Python?

defaults | overrides gives a new merged dict (Python 3.9+), and the right side wins on shared keys. update() changes one in place. Nested dicts are replaced.

Use |. It returns a new dictionary, and where both have the same key, the right-hand one wins.

python
defaults = {"theme": "light", "font_size": 14, "autosave": True}
user = {"theme": "dark", "font_size": 16}

settings = defaults | user
print(settings)
output
{'theme': 'dark', 'font_size': 16, 'autosave': True}

That "right wins" rule is what makes this useful: put the defaults on the left and whatever the user chose on the right.

Changing one in place

|= (or the older update()) changes the left dictionary instead of making a new one:

python
cart = {"pen": 2}
cart |= {"notebook": 1, "pen": 5}
print(cart)
output
{'pen': 5, 'notebook': 1}

On Python 3.8 or older

| arrived in Python 3.9. Before that, unpack both into a new dictionary. Same result, same "right wins" rule:

python
defaults = {"theme": "light", "font_size": 14}
user = {"theme": "dark"}

print({**defaults, **user})
output
{'theme': 'dark', 'font_size': 14}

The trap: nested dictionaries are replaced, not merged

The merge only looks at the top-level keys. If a value is itself a dictionary, the right-hand one replaces it whole:

python
defaults = {"editor": {"tabs": 4, "wrap": True}}
user = {"editor": {"tabs": 2}}

print(defaults | user)
output
{'editor': {'tabs': 2}}

wrap is gone. For config with nested sections, merge each level yourself:

python
def deep_merge(base, override):
    merged = dict(base)
    for key, value in override.items():
        if isinstance(value, dict) and isinstance(merged.get(key), dict):
            merged[key] = deep_merge(merged[key], value)
        else:
            merged[key] = value
    return merged

defaults = {"editor": {"tabs": 4, "wrap": True}, "theme": "light"}
user = {"editor": {"tabs": 2}}

print(deep_merge(defaults, user))
output
{'editor': {'tabs': 2, 'wrap': True}, 'theme': 'light'}

Adding up values instead of replacing them

If both dictionaries hold counts and you want them added, | is the wrong tool. Use Counter, which adds values on matching keys.

Go deeper: Dictionaries, Python Dictionary Cheat Sheet

More short answers

all questions