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

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

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

其他回答

>>> hash_1
{'a': 'foo', 'b': 'bar'}
>>> hash_2
{'a': 'foo', 'b': 'bar'}
>>> set_1 = set (hash_1.iteritems())
>>> set_1
set([('a', 'foo'), ('b', 'bar')])
>>> set_2 = set (hash_2.iteritems())
>>> set_2
set([('a', 'foo'), ('b', 'bar')])
>>> len (set_1.difference(set_2))
0
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...    print "The two hashes match."
...
The two hashes match.
>>> hash_2['c'] = 'baz'
>>> hash_2
{'a': 'foo', 'c': 'baz', 'b': 'bar'}
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...     print "The two hashes match."
...
>>>
>>> hash_2.pop('c')
'baz'

这是另一个选择:

>>> id(hash_1)
140640738806240
>>> id(hash_2)
140640738994848

所以你可以看到这两个id是不同的。但是丰富的比较操作符似乎可以做到这一点:

>>> hash_1 == hash_2
True
>>>
>>> hash_2
{'a': 'foo', 'b': 'bar'}
>>> set_2 = set (hash_2.iteritems())
>>> if (len(set_1.difference(set_2)) | len(set_2.difference(set_1))) == False:
...     print "The two hashes match."
...
The two hashes match.
>>>

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

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

@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
def dict_compare(d1, d2):
    d1_keys = set(d1.keys())
    d2_keys = set(d2.keys())
    shared_keys = d1_keys.intersection(d2_keys)
    added = d1_keys - d2_keys
    removed = d2_keys - d1_keys
    modified = {o : (d1[o], d2[o]) for o in shared_keys if d1[o] != d2[o]}
    same = set(o for o in shared_keys if d1[o] == d2[o])
    return added, removed, modified, same

x = dict(a=1, b=2)
y = dict(a=2, b=2)
added, removed, modified, same = dict_compare(x, y)

我是python的新手,但我最终做了类似于@mouad的事情

unmatched_item = set(dict_1.items()) ^ set(dict_2.items())
len(unmatched_item) # should be 0

异或操作符(^)应该删除字典中的所有元素,如果它们在两个字典中都相同。