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

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

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

我的问题:

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

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


当前回答

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

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

其他回答

参见字典视图对象: https://docs.python.org/2/library/stdtypes.html#dict

这样你可以从dictView1中减去dictView2,它将返回一组在dictView2中不同的键/值对:

original = {'one':1,'two':2,'ACTION':'ADD'}
originalView=original.viewitems()
updatedDict = {'one':1,'two':2,'ACTION':'REPLACE'}
updatedDictView=updatedDict.viewitems()
delta=original | updatedDict
print delta
>>set([('ACTION', 'REPLACE')])

你可以交叉,并,差(如上所示),对称差这些字典视图对象。 更好吗?更快呢?-不确定,但它是标准库的一部分-这使得它在可移植性方面有很大的优势

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。

你可以用下面的方法写出你自己的函数。

class Solution:
    def find_if_dict_equal(self,dict1,dict2):
        dict1_keys=list(dict1.keys())
        dict2_keys=list(dict2.keys())
        if len(dict1_keys)!=len(dict2_keys):
            return False
        for i in dict1_keys:
            if i not in dict2 or dict2[i]!=dict1[i]:
                return False
        return True
        
    def findAnagrams(self, s, p):
        if len(s)<len(p):
            return []
        p_dict={}
        for i in p:
            if i not in p_dict:
                p_dict[i]=0
            p_dict[i]+=1
        s_dict={}
        final_list=[]
        for i in s[:len(p)]:
            if i not in s_dict:
                s_dict[i]=0
            s_dict[i]+=1
        if self.find_if_dict_equal(s_dict,p_dict):
            final_list.append(0)
        for i in range(len(p),len(s)):
            element_to_add=s[i]
            element_to_remove=s[i-len(p)]
            if element_to_add not in s_dict:
                s_dict[element_to_add]=0
            s_dict[element_to_add]+=1
            s_dict[element_to_remove]-=1
            if s_dict[element_to_remove]==0:
                del s_dict[element_to_remove]
            if self.find_if_dict_equal(s_dict,p_dict):
                final_list.append(i-len(p)+1)
        return final_list

测试两个字典的键和值是否相等:

def dicts_equal(d1,d2):
    """ return True if all keys and values are the same """
    return all(k in d2 and d1[k] == d2[k]
               for k in d1) \
        and all(k in d1 and d1[k] == d2[k]
               for k in d2)

如果你想返回不同的值,请以不同的方式书写:

def dict1_minus_d2(d1, d2):
    """ return the subset of d1 where the keys don't exist in d2 or
        the values in d2 are different, as a dict """
    return {k,v for k,v in d1.items() if k in d2 and v == d2[k]}

你必须调用它两次,即

dict1_minus_d2(d1,d2).extend(dict1_minus_d2(d2,d1))

由于似乎没有人提到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}}}