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

ran*_*ght 43 python dictionary

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

match = True
for keys in dict1:
    if dict1[keys] != dict2[keys]:
        match = False
        print keys
        print dict1[keys],
        print  '->' ,
        print dict2[keys]
Run Code Online (Sandbox Code Playgroud)

编辑:两个词都包含相同的键.

Tho*_*asH 151

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

dict1 == dict2
Run Code Online (Sandbox Code Playgroud)

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

  • 键数(如果不匹配,则不相等)
  • 键的名称(如果它们不匹配,则它们不相等)
  • 每个键的值(它们也必须是'==')

最后一点再次显得微不足道,但实际上很有意思,因为它意味着所有这些都递归应用于嵌套的dicts.例如

 m1 = {'f':True}
 m2 = {'f':True}
 m3 = {'a':1, 2:2, 3:m1}
 m4 = {'a':1, 2:2, 3:m2}
 m3 == m4  # True
Run Code Online (Sandbox Code Playgroud)

对于列表的比较存在类似的语义.所有这些使得例如比较深Json结构,单独使用简单的"=="是一个明智的选择.

  • `所有这些都递归地应用于嵌套的dicts.这是明确记录的,以及对复杂嵌套结构的任何限制,例如dict列表的dict等? (9认同)
  • 我没有找到'递归地应用于嵌套dicts'部分的官方文档,但是,为了它的价值,在本节的[最后一句]中正式承诺了2 = dicts的`=='相等比较( https://docs.python.org/2/library/stdtypes.html#mapping-types-dict),你也可以在这个[分隔部分]中搜索"映射(dict的实例)比较相等"(https:/ /docs.python.org/2/reference/expressions.html#value-comparisons). (5认同)
  • 哇,这是真的 - "=="深入比较,至少对于基本类型!试试REPL:`a = {"a":False,'b':[1,2,{'foo':'bar','zamboni':是的,'奶酪':[False,[]]}, 3], 'C':无}; b = {'c':无,'a':错误,'b':[1,2,{'cheese':[False,[]],'foo':'bar','zamboni':True} ,3]}; a == b`.凉! (4认同)
  • 如果每个元素都得到`==`test并且任何元素都可以是dict,那么它当然会递归地应用于嵌套dicts. (2认同)

Ale*_*lli 40

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

diffkeys = [k for k in dict1 if dict1[k] != dict2[k]]
for k in diffkeys:
  print k, ':', dict1[k], '->', dict2[k]
Run Code Online (Sandbox Code Playgroud)

几乎与你所拥有的相同,但你可以通过在循环之前对diffkeys进行排序来获得更好的表示.

  • 执行 `dict2.get(k)` 更安全,因为它可能不存在。另外,如果您想真正比较这两种方式,您可能需要采取相反的方式,并且它只会从 dict1 键的角度进行检测,例如。当 dict2 有更多属性时 (2认同)

Joh*_*ooy 10

你也可以使用套装

>>> 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)])
Run Code Online (Sandbox Code Playgroud)

  • 除非其中一个值不可删除(例如,`list`),否则这非常有效.`set({'x':[]}.iteritems())`将引发一个`TypeError`. (3认同)

Joc*_*zel 7

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

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

  • 这就错过了dict2在dict1上有*附加*键的情况,所以它们的行为实际上并不相同. (3认同)