Last active
December 14, 2015 07:59
-
-
Save jerrykan/5054298 to your computer and use it in GitHub Desktop.
Given two dicts return another two dicts that contain only the differences between the original dicts
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
import unittest | |
def dict_diff(a, b): | |
if a == b: | |
return ({}, {}) | |
diff = ({}, {}) | |
keys = set(a.keys() + b.keys()) | |
for k in keys: | |
if k in a and k not in b: | |
diff[0][k] = a[k] | |
continue | |
if k not in a and k in b: | |
diff[1][k] = b[k] | |
continue | |
if a[k] != b[k]: | |
if type(a[k]) == type(b[k]) == dict: | |
diff[0][k], diff[1][k] = dict_diff(a[k], b[k]) | |
if not diff[0][k]: | |
del diff[0][k] | |
if not diff[1][k]: | |
del diff[1][k] | |
else: | |
diff[0][k] = a[k] | |
diff[1][k] = b[k] | |
return (diff[0], diff[1]) | |
class DictDiffTest(unittest.TestCase): | |
def test_1d_same(self): | |
a = {'a': 'a', 'b': 'b', 'c': 'c'} | |
b = {'a': 'a', 'b': 'b', 'c': 'c'} | |
self.assertEqual( | |
dict_diff(a, b), | |
({}, {}) | |
) | |
def test_1d_new_keys(self): | |
a = {'a': 'a', 'b': 'b'} | |
b = {'a': 'a', 'b': 'b', 'c': 'c'} | |
self.assertEqual( | |
dict_diff(a, b), | |
({}, {'c': 'c'}) | |
) | |
def test_1d_different_values(self): | |
a = {'a': 'a', 'b': 'b', 'c': 'c'} | |
b = {'a': 'a', 'b': 'bb', 'c': 'cc'} | |
self.assertEqual( | |
dict_diff(a, b), | |
({'b': 'b', 'c': 'c'}, {'b': 'bb', 'c': 'cc'}) | |
) | |
def test_1d_different_keys(self): | |
a = {'a': 'a', 'b': 'b', 'c': 'c'} | |
b = {'a': 'a', 'b': 'b', 'd': 'd'} | |
self.assertEqual( | |
dict_diff(a, b), | |
({'c': 'c'}, {'d': 'd'}) | |
) | |
def test_1d_different_keys_n_values(self): | |
a = {'a': 'a', 'b': 'b', 'c': 'c'} | |
b = {'a': 'a', 'b': 'bb', 'd': 'd'} | |
self.assertEqual( | |
dict_diff(a, b), | |
({'b': 'b', 'c': 'c'}, {'b': 'bb', 'd': 'd'}) | |
) | |
def test_2d_same(self): | |
a = {'a': {'1': '1'}, 'b': {'2': '2', '3': '3'}} | |
b = {'a': {'1': '1'}, 'b': {'2': '2', '3': '3'}} | |
self.assertEqual( | |
dict_diff(a, b), | |
({}, {}) | |
) | |
def test_2d_new_keys(self): | |
a = {'a': {'1': '1'}, 'b': {'2': '2'}} | |
b = {'a': {'1': '1', '2': '2'}, 'b': {'2': '2'}, 'c': 1} | |
self.assertEqual( | |
dict_diff(a, b), | |
({}, {'a': {'2': '2'}, 'c': 1}) | |
) | |
def test_2d_different_keys(self): | |
a = {'a': {'1': '1'}, 'b': {'2': '2', '3': '3'}} | |
b = {'a': {'1': '1'}, 'b': {'2': '2', '4': '4'}} | |
self.assertEqual( | |
dict_diff(a, b), | |
({'b': {'3': '3'}}, {'b': {'4': '4'}}) | |
) | |
def test_2d_different_values(self): | |
a = {'a': {}, 'b': {'2': '2', '3': '3'}} | |
b = {'a': {'1': '1'}, 'b': {'2': '2', '3': '33'}} | |
self.assertEqual( | |
dict_diff(a, b), | |
({'b': {'3': '3'}}, | |
{'a': {'1': '1'}, 'b': {'3': '33'}}) | |
) | |
def test_2d_different_values_n_keys(self): | |
a = {'a': {'1': '1'}, 'b': {'2': '2', '3': '3', '4': '4'}} | |
b = {'a': {'1': '11'}, 'b': {'2': '2', '3': '33', '5': '5'}} | |
self.assertEqual( | |
dict_diff(a, b), | |
({'a': {'1': '1'}, 'b': {'3': '3', '4': '4'}}, | |
{'a': {'1': '11'}, 'b': {'3': '33', '5': '5'}}) | |
) | |
if __name__ == '__main__': | |
suite = unittest.TestLoader().loadTestsFromTestCase(DictDiffTest) | |
unittest.TextTestRunner(verbosity=2, descriptions=False).run(suite) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment