from copy import deepcopy def jay_diff_rev(delta, data, temp_data): for k in data.keys(): if k not in temp_data: temp_data[k] = data[k] delta[k] = data[k] else: if isinstance(temp_data[k], dict): if k not in delta: delta[k] = {} jay_diff_rev(delta[k], data[k], temp_data[k]) def jay_diff_plus(_old, _new): __old = deepcopy(_old) delta = {} jay_diff_rev(delta, _new, __old) return delta def jay_diff_minus(_old, _new): __new = deepcopy(_new) delta = {} jay_diff_rev(delta, _old, __new) return delta def jay_diff_upd(temp_data, data): new_data = {} for k in data.keys(): if k in temp_data: if data[k] != temp_data[k]: new_data[k] = data[k] return new_data def jay_diff_full(data, temp_data): update = jay_diff_upd(data, temp_data) plus = jay_diff_plus(data, temp_data) minus = jay_diff_minus(data, temp_data) return {'diff': {'plus': plus, 'minus': minus, 'update': update}} def jay_merge_update(d, u): for k, v in u.items(): if isinstance(v, dict): r = jay_merge_update(d.get(k, {}), v) d[k] = r else: d[k] = u[k] return d def jay_merge_plus(d, u): for k, v in u.items(): if isinstance(v, dict): if k in d: d[k].update(v) else: d[k] = v else: d[k] = u[k] return d def jay_merge_minus(d, u): for k, v in u.items(): if isinstance(v, dict): jay_merge_minus(d[k], u[k]) else: if k in d: del d[k] return d if __name__ == '__main__': diffed = jay_diff_plus({}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}) assert diffed == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}} diffed = jay_diff_plus({'a':'hamburger', 'b':'fries', 'c':'pepsi'}, {'a':'hamburger', 'b':'fries', 'c':'coke'}) assert diffed == {} diffed = jay_diff_plus({'a':'hamburger', 'b':'fries', 'c':'pepsi', 'd':'icecream'}, {'a':'hamburger', 'b':'fries', 'c':'pepsi'}) assert diffed == {} diffed = jay_diff_plus({'a':'hamburger', 'b':'fries', 'c':'pepsi'}, {'a':'hamburger', 'd':'icecream', 'c':'coke'}) assert diffed == {'d':'icecream'} diffed = jay_diff_plus({'a':'hamburger', 'c':'pepsi', 'd':'icecream'}, {'a':'hamburger', 'b':'fries', 'c':'coke'}) assert diffed == {'b':'fries'} diffed = jay_diff_plus({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke'}}, {'c': {'f': 'coffee'}}) assert diffed == {'c': {'f': 'coffee'}} diffed = jay_diff_minus({'a':'hamburger', 'c':'pepsi', 'd':'icecream'}, {'a':'hamburger', 'b':'fries', 'c':'coke'}) assert diffed == {'d':'icecream'} diffed = jay_diff_minus({'a':'hamburger', 'b':'fries', 'c':'coke'}, {'a':'hamburger', 'b':'fries', 'c':'coke'}) assert diffed == {} diffed = jay_diff_minus({'a':'hamburger', 'b':'fries', 'c':'coke'}, {'a':'hamburger', 'b':'fries', 'c':'pepsi'}) assert diffed == {} diffed = jay_diff_minus({'a':'hamburger', 'b':'fries', 'c':'pepsi'}, {'a':'hamburger', 'b':'fries'}) assert diffed == {'c':'pepsi'} diffed = jay_diff_minus({'a':'hamburger', 'b':'fries', 'c':'pepsi'}, {'a':'hamburger', 'b':'fries', 'c':'coke'}) assert diffed == {} diffed = jay_diff_minus({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries'}) assert diffed == {'c': {'e': 'coke', 'f': 'coffee'}} diffed = jay_diff_minus({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}}) assert diffed == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}} diffed = jay_diff_upd({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes'}) assert diffed == {'a':'hotdog', 'b':'potatoes'} diffed = jay_diff_upd({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi'}}) assert diffed == {'c': {'e': 'pepsi'}} diffed = jay_diff_upd({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}) assert diffed == {'a':'hotdog'} diffed = jay_diff_upd({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}) assert diffed == {'c': {'e': 'pepsi'}} # ToDo: jay_diff_full merged = jay_merge_plus({}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}) assert merged == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}} merged = jay_merge_plus({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'d':'icecream'}) assert merged == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}, 'd':'icecream'} merged = jay_merge_minus({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}, 'd':'icecream'}, {'d':'icecream'}) assert merged == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}} merged = jay_merge_minus({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'f': 'coffee'}}) assert merged == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke'}} merged = jay_merge_minus({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}}) assert merged == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}} merged = jay_merge_plus({'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}}, {'d':'icecream'}) assert merged == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}, 'd':'icecream'} merged = jay_merge_plus({'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}, 'd':'icecream'}, {'d':'icecream'}) assert merged == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}, 'd':'icecream'}