Skip to content

Instantly share code, notes, and snippets.

@monester
Last active August 29, 2015 14:23
Show Gist options
  • Save monester/22c289b95c00a136fb1d to your computer and use it in GitHub Desktop.
Save monester/22c289b95c00a136fb1d to your computer and use it in GitHub Desktop.
Functions to create increment dict from old and new dict
def diff(new, old):
""" Return diff of elements
:param new:
:param old:
:return:
same: bool (if compared values the same)
value: dict || list || value (depends on income object)
"""
if type(new) != type(old):
return new
if type(old) in [int, float, long, str, unicode]:
if new == old:
return True, None
else:
return False, new
# creating new storage
new_obj = type(new)()
del_obj = type(new)()
if type(old) == dict:
# searching for removed or changed items
for old_key, old_item in old.iteritems():
if old_key in new:
if type(old_item) in [tuple, list, dict]:
same, no, do = diff(new[old_key], old[old_key])
if not same:
new_obj[old_key] = no
if do:
del_obj[old_key] = do
elif new[old_key] != old_item:
new_obj[old_key] = new[old_key]
else:
del_obj[old_key] = old_item
# searching for items only in new
for new_key, new_item in new.iteritems():
if new_key not in old:
new_obj[new_key] = new_item
elif type(old) in [list, tuple]:
for new_item in new:
if new_item not in old:
new_obj.append(new_item)
for old_item in old:
if old_item not in new:
del_obj.append(old_item)
else:
raise Exception('Unsupported type')
return type(new_obj)() == new_obj == del_obj, new_obj, del_obj
def merge(source, addobj, delobj=None):
if type(source) != type(addobj):
return addobj
if type(source) in [int, float, long, str, unicode]:
return addobj
new_obj = type(source)()
to_remove = lambda key: delobj[key] if type(delobj) in [dict, list] and key in delobj else None
if_hash = lambda h, k: h[k] if type(h) == dict and k in h else None
if type(new_obj) == dict:
# adding old values
for old_key, old_item in source.iteritems():
if type(old_item) in [list, dict]:
new_obj[old_key] = merge(
if_hash(source, old_key),
if_hash(addobj, old_key),
to_remove(old_key),
)
if not(type(delobj) == dict and old_key in delobj):
new_obj[old_key] = old_item
# adding new values
for new_key, new_item in addobj.iteritems():
if type(new_item) in [list, dict]:
new_obj[new_key] = merge(
if_hash(source, new_key),
if_hash(addobj, new_key),
to_remove(new_key),
)
else:
new_obj[new_key] = new_item
elif type(new_obj) == list:
for old_item in source:
if type(delobj) == list:
if old_item not in delobj:
new_obj.append(old_item)
else:
new_obj.append(old_item)
for new_item in addobj:
new_obj.append(new_item)
return new_obj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment