Skip to content

Instantly share code, notes, and snippets.

@jerrykan
Last active December 14, 2015 07:59
Show Gist options
  • Save jerrykan/5054298 to your computer and use it in GitHub Desktop.
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
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