Python字典的打印差异
我想拿两本字典,印一份。此差异应包括键和值之间的差异。我创建这个小片段是为了使用Python字典的打印差异,python,Python,我想拿两本字典,印一份。此差异应包括键和值之间的差异。我创建这个小片段是为了使用unittest模块中的内置代码获得结果。然而,这是一个令人讨厌的黑客行为,因为我必须将unittest.TestCase子类化,并提供一个runtest()方法让它工作。此外,此代码将导致应用程序出错,因为当存在差异时,它将引发AssertError。我真正想要的是打印差异 import unittest class tmp(unittest.TestCase): def __init__(self):
unittest
模块中的内置代码获得结果。然而,这是一个令人讨厌的黑客行为,因为我必须将unittest.TestCase
子类化,并提供一个runtest()
方法让它工作。此外,此代码将导致应用程序出错,因为当存在差异时,它将引发AssertError
。我真正想要的是打印差异
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)
我希望使用difflib
模块,但它似乎只适用于字符串。是否有一些方法可以解决这个问题,并且仍然使用difflib
?您可以使用.items()
和集合来执行类似的操作:
>>> 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)])
看。你能描述一下输出应该是什么样子吗(请附上一个例子)?你可以使用difflib,但是使用unittest方法对我来说似乎更合适。但是如果你想使用difflib。假设以下是两条格言
In [50]: dict1
Out[50]: {1: True, 2: False}
In [51]: dict2
Out[51]: {1: False, 2: True}
您可能需要将它们转换为字符串(或字符串列表),然后将difflib作为正常业务使用
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
产出将是:
--- dict1
+++ dict2
@@ -1,2 +1,2 @@
-1:True
-2:False
+1:False
+2:True
使用@并进一步满足OP的使用unittest
模块的请求
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)
def test_dict_diff(自):
dict_diff=list(set(self.dict_A.items()).symmetric_diff(set(self.dict_B.items()))
fail\u message=“差异太多:\n差异:\n”+
“%s”%“\n”。加入(dict\u diff)
self.assertTrue((len(dict_diff)
我发现了一个名为的库(没有很好的文档),它给出了python中散列数据结构的差异。您可以使用pip或easy_安装来安装它。试试看 退房
给出了我认为非常好的输出:
[('change', ['2014', 4, 'sum'], (-12140.0, -12141.0))]
i、 e.它给出了发生的情况:一个值“已更改”,路径“['2014',4',sum']”,它从-12140.0更改为-12141.0。改编自cpython源:
@MarkReed的可能副本--这是不同的。这要求键的差异,这要求键和值的差异(我假设OP需要键-值对)——例如,
{1:2,2:3}
不同于{1:3,2:2}
,但实际上没有明确说明…@mgilson-我没有提出关闭请求或将其标记为重复,但是如果你看一下那页上被接受的答案,它包括值比较,而不仅仅是键集比较。我不一定介意这个解决方案。然而,有没有办法把它清理一下?我想改变两件事:1。捕获/抑制AssertError(简单易做,但看起来很奇怪)2。使用assertDictEqual
而不必子类化TestCase
。我并没有真正设置打印格式。我想一些看起来像标准unidiff的东西会很好。但是,AssertDifferQual()的打印效果不错。下面是一些示例:断言错误:{'a':'a'}={'a':'abc'}-{'a':'a'}+{'a':'abc'}?++断言错误:{'a':1}={'a':2}-{'a':1}?^+{'a':2}^这看起来很酷。好主意。为什么你会说unittest方法在这里更合适?@durden2.0 unittest方法似乎提供了一种更简单的方法。无需转换为字符串等。这非常简洁,但我认为如果代码已经在使用unittest
模块,则使用内置的assertDictEqual()
是更好的解决方案。assertDictEqual
在2.7+我使用2.6。。。所以我想每个人都是这样P但是是的,那最好用。
[('change', ['2014', 4, 'sum'], (-12140.0, -12141.0))]
import difflib
import pprint
def compare_dicts(d1, d2):
return ('\n' + '\n'.join(difflib.ndiff(
pprint.pformat(d1).splitlines(),
pprint.pformat(d2).splitlines())))