Skip to content

Instantly share code, notes, and snippets.

@tomfa
Last active September 5, 2018 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomfa/4cbffe37ef8d817022f1bf995008b7a4 to your computer and use it in GitHub Desktop.
Save tomfa/4cbffe37ef8d817022f1bf995008b7a4 to your computer and use it in GitHub Desktop.
Python nested dict diff
"""
Hacky shell tool for finding dict deep diffs
a = {
'b': {
'c': 2,
'd': 3
},
'e': 2
}
b = {
'b': {
'c': 2,
'd': 4 # only diff
},
'e': 2
}
>>> flatten(a)
{'b_c': 2, 'b_d': 3, 'e': 2}
>>> diff(a, b)
{'b_d': '3 -> 4'}
"""
def flatten(data):
if type(data) not in (dict, list, set):
return {'': data}
if type(data) == set:
data = list(data)
return_data = {}
if type(data) == list:
for i, d in enumerate(data):
for k2, v2 in flatten(d).items():
if k2:
return_data[f'{i}_{k2}'] = v2
else:
return_data[f'{i}'] = v2
return return_data
for k, v in data.items():
for k2, v2 in flatten(v).items():
if k2:
return_data[f'{k}_{k2}'] = v2
else:
return_data[f'{k}'] = v2
return return_data
def diff(a, b):
a = flatten(a)
b = flatten(b)
old = {}
new = {}
for k, v in a.items():
if b.get(k) == v:
continue
old[k] = v
new[k] = b.get(k)
for k, v in b.items():
if a.get(k) == v:
continue
old[k] = a.get(k)
new[k] = v
all_keys = set(list(old.keys()) + list(new.keys()))
diff = {}
for k in all_keys:
diff[k] = f'{old.get(k)} -> {new.get(k)}'
return diff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment