9

2つの辞書を取り、それらの差分を印刷したいと思います。この差分には、キーと値の違いを含める必要があります。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か?

4

7 に答える 7

7

cpythonソースから適応:

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())))
于 2015-05-20T18:10:04.593 に答える
4

difflibを使用することもできますが、私にはuseunittestメソッドの方が適しているようです。ただし、difflibを使用したい場合。次の2つの口述があるとしましょう。

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
于 2012-10-18T14:50:34.630 に答える
2

.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)])
于 2012-10-18T14:30:15.943 に答える
1

私は、Pythonでハッシュ可能なデータ構造のdiffを提供するdatadiffと呼ばれるライブラリ(あまり文書化されていません)を見つけました。pipまたはeasy_installを使用してインストールできます。試してみる!

于 2013-10-29T11:00:56.410 に答える
0

2つの辞書の違いを(辞書として)作成するには、Pythonレシピを参照してください。出力がどのようになるか説明してください(例を添付してください)。

于 2012-10-18T14:36:17.910 に答える
0

@ mgilsonのソリューションunittestを使用し、OPの要求がモジュールで機能するようにさらに一歩進めます。

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)
于 2012-10-18T15:00:26.733 に答える
0

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),
    ]}))

私がかなり素晴らしいと思うこの出力を与えます:

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

つまり、何が起こったかを示します。値は「変更されました」、パスは「['2014'、4、'sum']」であり、-12140.0から-12141.0に変更されました。

于 2014-11-02T14:21:07.173 に答える