Last active
August 29, 2015 14:23
-
-
Save monester/22c289b95c00a136fb1d to your computer and use it in GitHub Desktop.
Functions to create increment dict from old and new dict
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
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