python-有没有更好的方法比较字典值

我目前正在使用以下函数比较字典值。 有更快或更更好的方法吗?

match = True
for keys in dict1:
if dict1[keys] != dict2[keys]:
match = False
print keys
print dict1[keys],
print '->' ,
print dict2[keys]

编辑:两个字典包含相同的键。

8个解决方案

150 votes

如果问题的真正目的是对各词之间的比较(而不是打印差异),那么答案是

dict1 == dict2

之前已经提到过这一点,但是我觉得它在其他信息中有些被淹没了。 它可能看起来很肤浅,但是字典的值比较实际上具有强大的语义。 它涵盖

键数(如果它们不匹配,则字典不相等)

键名(如果不匹配,则不相等)

每个键的值(也必须为'==')

最后一点似乎微不足道,但实际上很有趣,因为这意味着所有这些也递归地应用于嵌套字典。 例如。

m1 = {'f':True}
m2 = {'f':True}
m3 = {'a':1, 2:2, 3:m1}
m4 = {'a':1, 2:2, 3:m2}
m3 == m4 # True

存在用于列表比较的类似语义。 所有这些使它变得毫不费力,例如 比较深的Json结构,仅与简单的“ ==”进行比较。

ThomasH answered 2020-07-26T20:40:41Z

40 votes

如果字典具有相同的键集,并且您需要所有这些打印件以实现任何值差异,那么您将无能为力。 也许像这样:

diffkeys = [k for k in dict1 if dict1[k] != dict2[k]]
for k in diffkeys:
print k, ':', dict1[k], '->', dict2[k]

几乎等同于您所拥有的,但是您可能会得到更好的演示,例如在循环使用diffkey之前对它们进行排序。

Alex Martelli answered 2020-07-26T20:39:54Z

10 votes

您也可以为此使用集

>>> a = {'x': 1, 'y': 2}
>>> b = {'y': 2, 'x': 1}
>>> set(a.iteritems())-set(b.iteritems())
set([])
>>> a['y']=3
>>> set(a.iteritems())-set(b.iteritems())
set([('y', 3)])
>>> set(b.iteritems())-set(a.iteritems())
set([('y', 2)])
>>> set(b.iteritems())^set(a.iteritems())
set([('y', 3), ('y', 2)])
John La Rooy answered 2020-07-26T20:41:01Z

7 votes

嗯,您正在描述all( dict1[k]==dict2[k] for k in dict1 )(检查两个字典是否相等)

但是您的代码执行的是all( dict1[k]==dict2[k] for k in dict1 )(检查dict1中的所有条目是否等于dict2中的条目)

Jochen Ritzel answered 2020-07-26T20:41:26Z

2 votes

不确定这是否有帮助,但是在我的应用程序中,我必须检查字典是否已更改。

这样做是行不通的,因为基本上它仍然是同一对象:

val={'A':1,'B':2}
old_val=val
val['A']=10
if old_val != val:
print('changed')

使用复制/深复制的方法:

import copy
val={'A':1,'B':2}
old_val=copy.deepcopy(val)
val['A']=10
if old_val != val:
print('changed')
erazor answered 2020-07-26T20:41:54Z
1 votes
>>> a = {'x': 1, 'y': 2}
>>> b = {'y': 2, 'x': 1}
>>> print a == b
True
>>> c = {'z': 1}
>>> print a == c
False
>>>
yedpodtrzitko answered 2020-07-26T20:42:10Z

1 votes

如果您只是比较是否相等,则可以执行以下操作:

if not dict1 == dict2:

match = False

否则,我看到的唯一主要问题是,如果dict1中有一个键而不是dict2中的键,那么您将得到KeyError,因此您可能想要执行以下操作:

for key in dict1:
if not key in dict2 or dict1[key] != dict2[key]:
match = False

您可以将其压缩为一个综合信息,以获取不匹配的键列表:

mismatch_keys = [key for key in x if not key in y or x[key] != y[key]]
match = not bool(mismatch_keys) #If the list is not empty, they don't match
for key in mismatch_keys:
print key
print '%s -> %s' % (dict1[key],dict2[key])

我能想到的唯一的其他优化可能是使用“ len(dict)”来找出哪个dict的条目较少,并循环通过那个第一个,以实现尽可能短的循环。

Brent Writes Code answered 2020-07-26T20:42:43Z

0 votes

如果您的字典是深层嵌套的,并且包含不同类型的集合,则可以将它们转换为json字符串并进行比较。

import json

match = (json.dumps(dict1) == json.dumps(dict2))

请注意-如果您的字典中的值中包含二进制字符串,则此解决方案可能不起作用,因为这无法json序列化

user3283069 answered 2020-07-26T20:43:08Z