Python 比较两个字典并检查有多少(键,值)对相等
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4527942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing two dictionaries and checking how many (key, value) pairs are equal
提问by user225312
I have two dictionaries, but for simplification, I will take these two:
我有两本字典,但为简单起见,我将采用这两个:
>>> x = dict(a=1, b=2)
>>> y = dict(a=2, b=2)
Now, I want to compare whether each key, valuepair in xhas the same corresponding value in y. So I wrote this:
现在,我想比较 中的每一key, value对是否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
And it works since a tupleis returned and then compared for equality.
它的工作原理tuple是返回a然后比较相等性。
My questions:
我的问题:
Is this correct? Is there a betterway to do this? Better not in speed, I am talking about code elegance.
这样对吗?有没有更好的方法来做到这一点?最好不是速度,我说的是代码优雅。
UPDATE: I forgot to mention that I have to check how many key, valuepairs are equal.
更新:我忘了提到我必须检查有多少key, value对是相等的。
采纳答案by mouad
If you want to know how many values match in both the dictionaries, you should have said that :)
如果您想知道两个字典中匹配的值有多少,您应该说:)
Maybe something like this:
也许是这样的:
shared_items = {k: x[k] for k in x if k in y and x[k] == y[k]}
print len(shared_items)
回答by Jochen Ritzel
What you want to do is simply x==y
你想做的很简单 x==y
What you do is not a good idea, because the items in a dictionary are not supposed to have any order. You might be comparing [('a',1),('b',1)]with [('b',1), ('a',1)](same dictionaries, different order).
你这样做不是一个好主意,因为字典中的项目不应该有任何顺序。您可能正在[('a',1),('b',1)]与[('b',1), ('a',1)](相同的字典,不同的顺序)进行比较。
For example, see this:
例如,看这个:
>>> 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))]
The difference is only one item, but your algorithm will see that allitems are different
区别只是一个项目,但是你的算法会看到所有项目都不同
回答by philipp
I'm new to python but I ended up doing something similar to @mouad
我是 python 的新手,但我最终做了一些类似于 @mouad 的事情
unmatched_item = set(dict_1.items()) ^ set(dict_2.items())
len(unmatched_item) # should be 0
The XOR operator (^) should eliminate all elements of the dict when they are the same in both dicts.
^当两个字典中的元素相同时,XOR 运算符 ( ) 应该消除字典的所有元素。
回答by Daniel Myers
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)
回答by Alexander
@mouad 's answer is nice if you assume that both dictionaries contain simple values only. However, if you have dictionaries that contain dictionaries you'll get an exception as dictionaries are not hashable.
如果您假设两个字典都只包含简单值,@mouad 的回答很好。但是,如果您有包含字典的字典,您将得到一个异常,因为字典不可散列。
Off the top of my head, something like this might work:
在我的脑海里,这样的事情可能会奏效:
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
回答by Led Zeppelin
>>> 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'
Here's another option:
这是另一种选择:
>>> id(hash_1)
140640738806240
>>> id(hash_2)
140640738994848
So as you see the two id's are different. But the rich comparison operatorsseem to do the trick:
所以正如你所看到的,这两个 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.
>>>
回答by WoJ
Yet another possibility, up to the last note of the OP, is to compare the hashes (SHAor MD) of the dicts dumped as JSON. The way hashes are constructed guarantee that if they are equal, the source strings are equal as well. This is very fast and mathematically sound.
另一种可能性,直到 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))
回答by Shiyu
Just use:
只需使用:
assert cmp(dict1, dict2) == 0
回答by Mariusz K
import json
if json.dumps(dict1) == json.dumps(dict2):
print("Equal")
回答by CONvid19
dic1 == dic2
dic1 == dic2
From python docs:
来自python 文档:
To illustrate, the following examples all return a dictionary equalto
{"one": 1, "two": 2, "three": 3}:>>> a = dict(one=1, two=2, three=3) >>> b = {'one': 1, 'two': 2, 'three': 3} >>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3])) >>> d = dict([('two', 2), ('one', 1), ('three', 3)]) >>> e = dict({'three': 3, 'one': 1, 'two': 2}) >>> a == b == c == d == e TrueProviding keyword arguments as in the first example only works for keys that are valid Python identifiers. Otherwise, any valid keys can be used.
为了说明这一点,下面的例子都将返回一个字典等于到
{"one": 1, "two": 2, "three": 3}:>>> a = dict(one=1, two=2, three=3) >>> b = {'one': 1, 'two': 2, 'three': 3} >>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3])) >>> d = dict([('two', 2), ('one', 1), ('three', 3)]) >>> e = dict({'three': 3, 'one': 1, 'two': 2}) >>> a == b == c == d == e True在第一个示例中提供关键字参数仅适用于有效 Python 标识符的键。否则,可以使用任何有效的密钥。
Valid for both py2and py3.
对py2和都有效py3。

