繁体   English   中英

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

[英]Is there a better way to compare dictionary values

我目前正在使用以下函数来比较字典值并显示所有不匹配的值。 有没有更快或更好的方法来做到这一点?

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

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

如果问题的真正意图是字典之间的比较(而不是打印差异),那么答案是

dict1 == dict2

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

  • 键的数量(如果它们不匹配,则字典不相等)
  • 键名(如果不匹配,则不相等)
  • 每个键的值(它们也必须是“==”)

最后一点再次显得微不足道,但实际上很有趣,因为这意味着所有这些都递归适用于嵌套的字典。 例如

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

列表的比较存在类似的语义。 所有这一切都使得比较深层的 Json 结构变得轻而易举,单独使用一个简单的“==”。

如果 dicts 具有相同的键集,并且您需要所有这些打印来处理任何值差异,那么您无能为力; 也许是这样的:

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

几乎等同于您拥有的内容,但您可能会获得更好的演示,例如在循环之前对差异键进行排序。

您也可以为此使用集合

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

嗯,你在描述dict1 == dict2 (检查两个字典是否相等)

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

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

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

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

如果你只是比较平等,你可以这样做:

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 的条目较少,然后首先循环遍历该条目以获得尽可能短的循环。

>>> a = {'x': 1, 'y': 2}
>>> b = {'y': 2, 'x': 1}
>>> print a == b
True
>>> c = {'z': 1}
>>> print a == c
False
>>> 

如果您的值是可散列的(即字符串),那么您可以简单地比较两个字典的 ItemsView。

https://docs.python.org/3/library/stdtypes.html#dict-views

set_with_unique_key_value_pairs = dict1.items() ^ dict2.items()
set_with_matching_key_value_pairs = dict1.items() & dict2.items()

您可以使用任何set操作。

由于在这种情况下您可能不关心键,您也可以只使用 ValuesView(同样,如果值是可散列的)。

set_with_matching_values = dict1.values() & dict2.values()

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM