Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python字典的打印差异_Python - Fatal编程技术网

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())))