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

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

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

我的问题:

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

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


当前回答

迟回复总比不回复好!

比较Not_Equal比比较Equal更有效。因此,如果一个字典中的任何键值在另一个字典中找不到,那么两个字典就不相等。下面的代码考虑到您可能会比较默认的dict,因此使用get而不是getitem[]。

在get调用中使用一种随机值作为默认值,等于要检索的键-以防dicts在一个dict中有None作为值,而该键在另一个dict中不存在。此外,为了提高效率,get !=条件是在not in条件之前检查的,因为您同时对两边的键和值进行检查。

def Dicts_Not_Equal(first,second):
    """ return True if both do not have same length or if any keys and values are not the same """
    if len(first) == len(second): 
        for k in first:
            if first.get(k) != second.get(k,k) or k not in second: return (True)
        for k in second:         
            if first.get(k,k) != second.get(k) or k not in first: return (True)
        return (False)   
    return (True)

其他回答

只使用:

assert cmp(dict1, dict2) == 0

参见字典视图对象: 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')])

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

你要做的就是x==y

你这样做不是一个好主意,因为字典里的条目不应该有任何顺序。你可能会比较[('a',1),('b',1)]和[('b',1), ('a',1)](相同的字典,不同的顺序)。

例如,看这个:

>>> x = dict(a=2, b=2,c=3, d=4)
>>> x
{'a': 2, 'c': 3, 'b': 2, 'd': 4}
>>> y = dict(b=2,c=3, d=4)
>>> y
{'c': 3, 'b': 2, 'd': 4}
>>> zip(x.iteritems(), y.iteritems())
[(('a', 2), ('c', 3)), (('c', 3), ('b', 2)), (('b', 2), ('d', 4))]

虽然只有一项不同,但你的算法会发现所有项都是不同的

python3:

data_set_a = dict_a.items()
data_set_b = dict_b.items()

difference_set = data_set_a ^ data_set_b

我正在使用这个解决方案,在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树”中添加一个新的分支。

希望这能有所帮助。