Skip to content

Instantly share code, notes, and snippets.

@maxpeterson
Last active September 2, 2016 09:54
Show Gist options
  • Save maxpeterson/ff657a282918a1d31787de733c5458ad to your computer and use it in GitHub Desktop.
Save maxpeterson/ff657a282918a1d31787de733c5458ad to your computer and use it in GitHub Desktop.
Compare hierarchical dict / list like structures
def compare_json(first, second, keys=None):
if first == second:
return True
if keys is None:
keys = []
def prefix(keys):
return '[{}]'.format(']['.join(keys))
# Used to keep track of whether we have already detected the difference (and reported
# the error).
same = True
if isinstance(first, dict) and isinstance(second, dict):
for key in set(list(first.keys()) + list(second.keys())):
subkeys = keys + [key]
if key not in first:
print("Key '{}' not in first\n".format(prefix(subkeys)))
same = False
continue
if key not in second:
print("Key '{}' not in second\n".format(prefix(subkeys)))
same = False
continue
if not compare_json(first[key], second[key], subkeys):
same = False
if isinstance(first, (list, tuple)) and isinstance(second, (list, tuple)):
lfirst = len(first)
lsecond = len(second)
if lfirst > lsecond:
print('items in first not in second{} {}\n'.format(
prefix(keys),
repr(first[lsecond:]),
))
same = False
if lsecond > lfirst:
print('items in first not in second{} {}\n'.format(
prefix(keys),
repr(second[lfirst:]),
))
same = False
for (i, (f, s)) in enumerate(zip(first, second)):
if not compare_json(f, s, keys + [str(i)]):
same = False
if same:
# They can't be the same if we reach this point but we have failed to detect it so
# assume that at least one object is not a list / dict and report them.
print("First {0} is not equal to Second {0}\n".format(prefix(keys)))
return False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment