Skip to content

Instantly share code, notes, and snippets.

@shawnohare
Created July 7, 2023 18:42
Show Gist options
  • Save shawnohare/62d8c7ff1248cd937b22a9d5237cf145 to your computer and use it in GitHub Desktop.
Save shawnohare/62d8c7ff1248cd937b22a9d5237cf145 to your computer and use it in GitHub Desktop.
Python recursive dict merge
def merge(d1: dict, d2: dict) -> dict:
"""Return a new dict instance containing the recursive
merge of d2 into d1. Neither input is mutated.
"""
d1 = deepcopy(d1)
d2 = deepcopy(d2)
for k2, v2 in d2.items():
if isinstance(v2, dict) and isinstance(v1 := d1.get(k2), dict):
v2 = merge(v1, v2)
d1[k2] = v2
return d1
def tests():
cases = [
({}, {}, {}),
({0:0}, {}, {0:0}),
({0:0}, {0: 1}, {0: 1}),
({0:0, 1:1}, {0: 1}, {0: 1, 1:1}),
({'a':0}, {'a': {'b': 0}}, {'a': {'b': 0}}),
({'a':{'b': None, 'c': 0}}, {'a': {'b': 0}}, {'a': {'b': 0, 'c': 0}}),
]
for i, (d1, d2, expected) in enumerate(cases):
try:
actual = merge(d1, d2)
assert(actual == expected)
except AssertionError:
print(f"test case {i} failed")
print("Expected:")
print(expected)
print("Actual:")
print(actual)
else:
print(f"test case {i} passed")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment