我有两本字典,但为了简化起见,我就选这两本:

>>> x = dict(a=1, b=2)
>>> y = dict(a=2, b=2)

现在,我想比较x中的每个键值对在y中是否有相同的对应值,所以我这样写:

>>> for x_values, y_values in zip(x.iteritems(), y.iteritems()):
        if x_values == y_values:
            print 'Ok', x_values, y_values
        else:
            print 'Not', x_values, y_values

它的工作原理是返回一个元组,然后比较是否相等。

我的问题:

这对吗?还有更好的办法吗?最好不是在速度上,我说的是代码优雅。

更新:我忘了提到,我必须检查有多少键,值对是相等的。


当前回答

@mouad的答案很好,如果你假设两个字典都只包含简单的值。然而,如果你有包含字典的字典,你会得到一个异常,因为字典是不可哈希的。

在我的脑海中,这样做可能有用:

def compare_dictionaries(dict1, dict2):
     if dict1 is None or dict2 is None:
        print('Nones')
        return False

     if (not isinstance(dict1, dict)) or (not isinstance(dict2, dict)):
        print('Not dict')
        return False

     shared_keys = set(dict1.keys()) & set(dict2.keys())

     if not ( len(shared_keys) == len(dict1.keys()) and len(shared_keys) == len(dict2.keys())):
        print('Not all keys are shared')
        return False


     dicts_are_equal = True
     for key in dict1.keys():
         if isinstance(dict1[key], dict) or isinstance(dict2[key], dict):
             dicts_are_equal = dicts_are_equal and compare_dictionaries(dict1[key], dict2[key])
         else:
             dicts_are_equal = dicts_are_equal and all(atleast_1d(dict1[key] == dict2[key]))

     return dicts_are_equal

其他回答

dic1 == dic2

来自python文档:

下面的例子都返回一个字典等于 {" 1 ": 1, " 2 ": 2, " 3 ": 3}: >>> a = dict(1 =1, 2 =2, 3 =3) >>> b = {' 1 ': 1, ' 2 ': 2, ' 3 ': 3} > > > c = dict (zip([“一”,“两个”,“三”],[1,2,3])) > > > d = dict([(2, 2),('一',1),(‘三’,3))) >>> e = dict({'三':3,'一':1,'二':2}) a == b == c == d == e 真正的

在第一个例子中提供关键字参数只适用于 是有效的Python标识符的键。否则,任何有效的密钥都可以 被使用。

适用于python2和python3。

为什么不只是遍历一个字典,并在过程中检查另一个字典(假设两个字典都有相同的键)?

x = dict(a=1, b=2)
y = dict(a=2, b=2)

for key, val in x.items():
    if val == y[key]:
        print ('Ok', val, y[key])
    else:
        print ('Not', val, y[key])

输出:

Not 1 2
Ok 2 2
import json

if json.dumps(dict1) == json.dumps(dict2):
    print("Equal")

对两个字典进行深度比较的最简单的方法(也是最健壮的方法之一)是将它们序列化为JSON格式,对键进行排序,并比较字符串结果:

import json
if json.dumps(x, sort_keys=True) == json.dumps(y, sort_keys=True):
   ... Do something ...

由于似乎没有人提到deepdiff,为了完整起见,我将在这里添加它。我发现它非常方便获得(嵌套)对象的差异:

安装

pip install deepdiff

示例代码

import deepdiff
import json

dict_1 = {
    "a": 1,
    "nested": {
        "b": 1,
    }
}

dict_2 = {
    "a": 2,
    "nested": {
        "b": 2,
    }
}

diff = deepdiff.DeepDiff(dict_1, dict_2)
print(json.dumps(diff, indent=4))

输出

{
    "values_changed": {
        "root['a']": {
            "new_value": 2,
            "old_value": 1
        },
        "root['nested']['b']": {
            "new_value": 2,
            "old_value": 1
        }
    }
}

注意关于检查结果的漂亮打印:如果两个字典具有相同的属性键(可能与示例中的属性值不同),上面的代码就可以工作。但是,如果存在一个“extra”属性是字典之一,json.dumps()将失败

TypeError: Object of type PrettyOrderedSet is not JSON serializable

解决方案:使用diff.to_json()和json.loads() / json.dumps()来漂亮地打印:

import deepdiff
import json

dict_1 = {
    "a": 1,
    "nested": {
        "b": 1,
    },
    "extra": 3
}

dict_2 = {
    "a": 2,
    "nested": {
        "b": 2,
    }
}

diff = deepdiff.DeepDiff(dict_1, dict_2)
print(json.dumps(json.loads(diff.to_json()), indent=4))  

输出:

{
    "dictionary_item_removed": [
        "root['extra']"
    ],
    "values_changed": {
        "root['a']": {
            "new_value": 2,
            "old_value": 1
        },
        "root['nested']['b']": {
            "new_value": 2,
            "old_value": 1
        }
    }
}

替代方案:使用pprint,结果是不同的格式:

import pprint

# same code as above

pprint.pprint(diff, indent=4)

输出:

{   'dictionary_item_removed': [root['extra']],
    'values_changed': {   "root['a']": {   'new_value': 2,
                                           'old_value': 1},
                          "root['nested']['b']": {   'new_value': 2,
                                                     'old_value': 1}}}