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

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

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

我的问题:

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

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


当前回答

现在简单的比较==就足够了(python 3.8)。即使当你以不同的顺序比较相同的字典(上一个例子)。最好的是,您不需要第三方包来完成此任务。

a = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}
b = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}

c = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}
d = {'one': 'dog', 'two': 'cat', 'three': 'mouse', 'four': 'fish'}

e = {'one': 'cat', 'two': 'dog', 'three': 'mouse'}
f = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}

g = {'two': 'cat', 'one': 'dog', 'three': 'mouse'}
h = {'one': 'dog', 'two': 'cat', 'three': 'mouse'}


print(a == b) # True
print(c == d) # False
print(e == f) # False
print(g == h) # True

其他回答

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

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

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

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

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

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

还有一种可能,直到OP的最后一个音符,是比较转储为JSON的字典的哈希值(SHA或MD)。构造哈希的方式保证如果它们相等,源字符串也相等。这是非常快速和数学上合理的。

import json
import hashlib

def hash_dict(d):
    return hashlib.sha1(json.dumps(d, sort_keys=True)).hexdigest()

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

print(hash_dict(x) == hash_dict(y))
print(hash_dict(x) == hash_dict(z))

我正在使用这个解决方案,在Python 3中完美地为我工作


import logging
log = logging.getLogger(__name__)

...

    def deep_compare(self,left, right, level=0):
        if type(left) != type(right):
            log.info("Exit 1 - Different types")
            return False

        elif type(left) is dict:
            # Dict comparison
            for key in left:
                if key not in right:
                    log.info("Exit 2 - missing {} in right".format(key))
                    return False
                else:
                    if not deep_compare(left[str(key)], right[str(key)], level +1 ):
                        log.info("Exit 3 - different children")
                        return False
            return True
        elif type(left) is list:
            # List comparison
            for key in left:
                if key not in right:
                    log.info("Exit 4 - missing {} in right".format(key))
                    return False
                else:
                    if not deep_compare(left[left.index(key)], right[right.index(key)], level +1 ):
                        log.info("Exit 5 - different children")
                        return False
            return True
        else:
            # Other comparison
            return left == right

        return False

它比较dict、list和其他单独实现“==”操作符的类型。 如果你需要比较其他不同的东西,你需要在“If树”中添加一个新的分支。

希望这能有所帮助。