Skip to content

Instantly share code, notes, and snippets.

@jerrykan jerrykan/dict_diff.py
Last active Dec 14, 2015

Embed
What would you like to do?
Given two dicts return another two dicts that contain only the differences between the original dicts
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
You can’t perform that action at this time.