比较2个词典:相同的键,不匹配的值

时间:2016-05-24 23:35:30

标签: python

我目前正在尝试比较2个数据集:

dict1 = {'a':1, 'b':2, 'c':3}
dict2 = {'a':1, 'b':2, 'c':4}

在这种情况下,我希望输出类似于:

set1 = set([('c', 4), ('c',3)])

因为它们的键匹配但值不匹配。

我尝试使用交集和差异运算符进行了一系列的理解,但我无法获得所需的输出。

感谢任何帮助。

8 个答案:

答案 0 :(得分:9)

如果您使用的是Python 2:

dict1.viewitems() ^ dict2.viewitems()

如果您使用的是Python 3:

dict1.items() ^ dict2.items()

viewitems(Python 2)和items(Python 3)返回一个类似于集合的对象,我们可以使用插入符号运算符来计算对称差异。

答案 1 :(得分:5)

iteritems

在Python 2中使用echo "<td><input type=\"radio\" class=\"wanted[]\" name=\"wanted[]\" value='$title'></td></tr>"; 以提高效率。

答案 2 :(得分:2)

你想要的是MultiDict。它们不存在于python的标准库中,但是受欢迎的boltons包有它们。它们允许您在同一个字段中存储多个键。

from boltons.dictutils import MultiDict

dict1 = {'a':1, 'b':2, 'c':3}
dict2 = {'a':1, 'b':2, 'c':4}

m = MultiDict()
for k in dict1.keys():
    if dict1.get(k) != dict2.get(k):
        m.add(k, dict1.get(k))
        m.add(k, dict2.get(k))

print m
for k in m.keys():
    print k, m.getlist(k)

# OrderedMultiDict([('c', 3), ('c', 4)])
# 'c' [3, 4]

答案 3 :(得分:1)

这在Python中是不可能的。字典是具有唯一键的数据结构,因此无论值是什么,您都不能在同一个字典中使用相同的键两次。

作为替代方案,您可能希望为每个重复的密钥生成元组列表(键,值)。

l = [(k,v,k,dict2[k]) for k,v in dict1 if k in dict2]

答案 4 :(得分:1)

将词典变成成对的组;从两个方面获取集合差异并合并列表:

[('c', 3), ('c', 4)]

输出:

dict1 = {'a':1, 'b':2, 'c':3}
dict2 = {'a':1, 'b':2, 'c':4}

set1 = set(dict1.items())
set2 = set(dict2.items())
diff_set = set1 ^ set2
print diff_set

根据Peter Wood的观察编辑:

{{1}}

答案 5 :(得分:1)

 for key, val in dict1.iteritems():
   if key in dict2 and val != dict2[key]:
     set1.add((key, val))

 for key, val in dict2.iteritems():
   if key in dict1 and val != dict1[key]:
     set1.add((key, val))

答案 6 :(得分:1)

这让你相当接近:

for value in zip(dict1.iteritems(), dict2.iteritems()):
    if(value[0] != value[1]):
        tuple = value
print tuple

(('c',3),('c',4))

答案 7 :(得分:1)

您可以使用set并点击symmetric_difference

set(dict1.items()) ^ set(dict2.items())

编辑:我使用timeit调查了Python 2的性能。

最快 set(dict1.viewitems()).symmetric_difference(dict2.viewitems())

关闭第二个,最可读的是 dict1.viewitems() ^ dict2.viewitems()

最糟糕的是我的答案 set(dict1.items()) ^ set(dict2.items())

>>> from timeit import timeit

>>> setup = ('dict1 = {str(i): i for i in range(1000)}; '
...          'dict2 = {str(i): (i if i % 10 else i - 1) for i in range(1000)}')

这为我们提供了两个词典,1000条目和10%不同,即200对称差异:

>>> exec(setup)
>>> len(dict1.viewitems() ^ dict2.viewitems())
200

我们将检查每个案例30000次:

>>> def check(expression):
...     return timeit(expression, setup, number=30000)

时间,最好到最差:

>>> check('set(dict1.viewitems()).symmetric_difference(dict2.viewitems())')
8.233164442241105

>>> check('dict1.viewitems() ^ dict2.viewitems()')
8.242523450809585

>>> check('set(dict1.viewitems()).symmetric_difference(dict2.items())')
8.651751725357371

>>> check('set(dict1.items()).symmetric_difference(dict2.items())')
8.774394999897368

>>> check('set(dict1.items()) ^ set(dict2.items())')
9.795530728021276