Skip to content

S2Q1 · Merge Two Dictionaries and Sum on Conflicts

⚡ Quick Reference

Function: merge_dictionaries(d1: dict, d2: dict) -> dict

Core idea: start with a copy of d1, then for each key in d2 add its value to the existing value (or insert it if new).

def merge_dictionaries(d1: dict, d2: dict) -> dict:
    result = dict(d1)
    for key, value in d2.items():
        result[key] = result.get(key, 0) + value
    return result

Key rules: - Keys unique to d1 or d2 → included as-is - Keys in both → values are summed - Original dicts must not be modified - work on a copy of d1


Problem Statement

Problem

Write a function merge_dictionaries(d1, d2) that merges two dictionaries, summing values for keys that appear in both.

Example:

Input
d1={"a": 1, "b": 2}, d2={"b": 3, "c": 4}
Output
{"a": 1, "b": 5, "c": 4}

"b" appears in both → 2 + 3 = 5. "a" only in d1 → 1. "c" only in d2 → 4.


Tracing the example

Key In d1? In d2? Value Result
"a" ✅ (1) as-is 1
"b" ✅ (2) ✅ (3) 2 + 3 5
"c" ✅ (4) as-is 4

Output: {"a": 1, "b": 5, "c": 4}


Solution approaches

def merge_dictionaries(d1: dict, d2: dict) -> dict:
    result = dict(d1)                          # copy d1
    for key, value in d2.items():
        result[key] = result.get(key, 0) + value
    return result
def merge_dictionaries(d1: dict, d2: dict) -> dict:
    result = dict(d1)    # start with all keys from d1
    for key, value in d2.items():
        if key in result:
            result[key] += value    # sum on conflict
        else:
            result[key] = value     # new key - insert as-is
    return result
from collections import Counter

def merge_dictionaries(d1: dict, d2: dict) -> dict:
    return dict(Counter(d1) + Counter(d2))

Counter supports + which sums values for matching keys and includes all unique keys. Clean one-liner - note that Counter drops zero/negative results, which is fine here since values are positive numbers.

def merge_dictionaries(d1: dict, d2: dict) -> dict:
    all_keys = d1.keys() | d2.keys()    # union of all keys
    return {k: d1.get(k, 0) + d2.get(k, 0) for k in all_keys}

Takes the union of all keys, then for each key sums the value from d1 (defaulting to 0) and d2 (defaulting to 0). Elegant and symmetric - treats both dicts equally.

from functools import reduce

def merge_dictionaries(d1: dict, d2: dict) -> dict:
    merge = lambda acc, kv: {**acc, kv[0]: acc.get(kv[0], 0) + kv[1]}
    return reduce(merge, d2.items(), dict(d1))

Key takeaways

01

Copy d1 first - don't modify the original

result = dict(d1) creates a shallow copy. Modifying result leaves d1 unchanged. Using result = d1 would make them point to the same object - any changes would affect d1.

02

result.get(key, 0) handles both cases in one line

If the key already exists in result, .get() returns its current value. If it's new (only in d2), it returns 0. Adding the d2 value works correctly either way - no if key in result needed.

03

d1.keys() | d2.keys() - set union of all keys

Dict key views support set operations. | gives the union - all keys from both dicts without duplicates. Paired with .get(k, 0) for both dicts, this handles all three cases (d1-only, d2-only, both) uniformly.