Print diff from Python dictionaries

I want to take two dictionaries and print them. This diff should include differences in the values ​​of the AND keys. I created this small snippet to achieve results using the inline code in the unittest module. However, this is an unpleasant hack, as I have to subclass unittest.TestCase and provide a runtest() method for it to work. In addition, this code will cause an application error because AssertError will be raised when differences AssertError . All I really want is to print diff.

 import unittest class tmp(unittest.TestCase): def __init__(self): # Show full diff of objects (dicts could be HUGE and output truncated) self.maxDiff = None def runTest(): pass _ = tmp() _.assertDictEqual(d1, d2) 

I was hoping to use the difflib module, but it only works for strings. Is there any way around this and using difflib ?

+4
source share
7 answers

You can use difflib, but the unittest method seems more appropriate to me. But if you want to use difflib. Say, let's say that these are two dictates.

 In [50]: dict1 Out[50]: {1: True, 2: False} In [51]: dict2 Out[51]: {1: False, 2: True} 

You may need to convert them to strings (or a list of strings) and then use difflib as a regular business.

 In [43]: a = '\n'.join(['%s:%s' % (key, value) for (key, value) in sorted(dict1.items())]) In [44]: b = '\n'.join(['%s:%s' % (key, value) for (key, value) in sorted(dict2.items())]) In [45]: print a 1:True 2:False In [46]: print b 1:False 2:True In [47]: for diffs in difflib.unified_diff(a.splitlines(), b.splitlines(), fromfile='dict1', tofile='dict2'): print diffs 

Output:

 --- dict1 +++ dict2 @@ -1,2 +1,2 @@ -1:True -2:False +1:False +2:True 
+1
source

Adapted from cpython source:

https://github.com/python/cpython/blob/01fd68752e2d2d0a5f90ae8944ca35df0a5ddeaa/Lib/unittest/case.py#L1091

 import difflib import pprint def compare_dicts(d1, d2): return ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) 
+2
source

You can use .items() along with sets to do something like this:

 >>> d = dict((i,i) for i in range(10)) >>> d2 = dict((i,i) for i in range(1,11)) >>> >>> set(d.items()) - set(d2.items()) set([(0, 0)]) >>> >>> set(d2.items()) - set(d.items()) set([(10, 10)]) >>> >>> set(d2.items()) ^ set(d.items()) #symmetric difference set([(0, 0), (10, 10)]) >>> set(d2.items()).symmetric_difference(d.items()) #only need to actually create 1 set set([(0, 0), (10, 10)]) 
+1
source

I found a library (not very well-documented) called datadiff that produces the difference of hashed data structures in python. you can install it using pip or easy_install. Give it a try!

+1
source

See the Python recipe to make the difference (like a dictionary) of two dictionaries . Could you describe what the output should look like (please attach an example)?

0
source

using @ mgilson's solution and taking one more step to query OP to work with unittest module.

 def test_dict_diff(self): dict_diff = list(set(self.dict_A.items()).symmetric_difference(set(self.dict_B.items())))) fail_message = "too many differences:\nThe differences:\n" + "%s" % "\n".join(dict_diff) self.assertTrue((len(dict_diff) < self.maxDiff), fail_message) 
0
source

Check out https://github.com/inveniosoftware/dictdiffer

 print list(diff( {2014: [ dict(month=6, category=None, sum=672.00), dict(month=6, category=1, sum=-8954.00), dict(month=7, category=None, sum=7475.17), dict(month=7, category=1, sum=-11745.00), dict(month=8, category=None, sum=-12140.00), dict(month=8, category=1, sum=-11812.00), dict(month=9, category=None, sum=-31719.41), dict(month=9, category=1, sum=-11663.00), ]}, {2014: [ dict(month=6, category=None, sum=672.00), dict(month=6, category=1, sum=-8954.00), dict(month=7, category=None, sum=7475.17), dict(month=7, category=1, sum=-11745.00), dict(month=8, category=None, sum=-12141.00), dict(month=8, category=1, sum=-11812.00), dict(month=9, category=None, sum=-31719.41), dict(month=9, category=1, sum=-11663.00), ]})) 

gives this result, which I find pretty good:

 [('change', ['2014', 4, 'sum'], (-12140.0, -12141.0))] 

i.e. it gives what happened: the meaning of β€œchanged”, the path β€œ[2014”, 4, β€œamount”] and that it changed from -12140.0 to -12141.0.

0
source

Source: https://habr.com/ru/post/1440563/


All Articles