Last active
July 13, 2017 07:40
-
-
Save neilalexander/f2f00016eb001da8e5e364b809a58635 to your computer and use it in GitHub Desktop.
Python 3 functions for comparing complex dict structures for additions, changes and deletions, and for walking the tree and running a given function on nodes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DeltaDict: | |
# | |
# changes(dict1, dict2) returns dict | |
# | |
# Finds nodes that appear in both dict1 and dict2 but | |
# where the values have changed | |
# | |
def changes(d1, d2): | |
d = dict() | |
s = set(d1.keys()).intersection(set(d2.keys())) | |
try: | |
for k in { o : d2[o] for o in s if d1[o] != d2[o] }: | |
a = DeltaDict.changes(d1[k], d2[k]) | |
if a != {}: | |
d[k] = a | |
except: | |
d[k] = d2[k] | |
return d | |
# | |
# additions(dict1, dict2) returns dict | |
# | |
# Finds nodes that appear in dict2 but not in dict1 | |
# | |
def additions(d1, d2): | |
d = dict() | |
for k, v in d2.items(): | |
try: d1[k] | |
except: | |
if type(v) is not dict: d[k] = v | |
if type(v) is dict: | |
try: a = DeltaDict.additions(d1[k], d2[k]) | |
except KeyError: a = DeltaDict.additions({}, d2[k]) | |
if a != {}: | |
d[k] = a | |
return d | |
# | |
# deletions(dict1, dict2) returns dict | |
# | |
# Finds nodes that appear in dict1 but not in dict2 | |
# | |
def deletions(d1, d2): | |
d = dict() | |
for k, v in d1.items(): | |
try: | |
if d2[k] and type(v) is dict: | |
try: a = DeltaDict.deletions(d1[k], d2[k]) | |
except KeyError: a = DeltaDict.deletions(d1[k], {}) | |
if a != {}: | |
d[k] = a | |
except: | |
if v != {}: | |
d[k] = v | |
return d | |
# | |
# walkall(dict, function) yields path, returnval | |
# | |
# Walks all nodes of the given dict structure, including | |
# inner nodes | |
# | |
def walkall(d, f, p = []): | |
for k, v in d.items(): | |
p.append(k) | |
if type(v) is dict: | |
yield from DeltaDict.walkall(v, f, p) | |
yield p, f(v) | |
p.pop() | |
# | |
# walkleaf(dict, function) yields path, returnval | |
# | |
# Walks only leaf nodes of the given dict structure, not | |
# including inner nodes | |
# | |
def walkleaf(d, f, p = []): | |
for k, v in d.items(): | |
p.append(k); | |
if type(v) is dict: | |
yield from DeltaDict.walkleaf(v, f, p) | |
else: | |
yield p, f(v) | |
p.pop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment