我必须比较python中的2个词典。例如,我使用下面的代码,如果在di1和di2中key:value对的数量相同但是如果di2中缺少key:value对则代码失败,那么它工作正常。
di1 = {'Name': 'cat', 'Age': 9,'Alpha':'mat','Beta':'deep'};
di2 = {'Name': 'cat', 'Age': 27,'Alpha':'rat'};
dicdiff = [k for k in di1 if di1[k] != di2[k]]
for k in dicdiff:
print k, ':', di1[k], '->', di2[k]
答案 0 :(得分:2)
使用dictionary view objects并使用设置操作:
for key, value in di1.viewitems() ^ di2.viewitems():
print '{!r}: {!r}'.format(key, value)
^
为我们提供了两个词典之间的对称差异;这将列出任一字典中存在的键,但缺少其他字典中的键,和值不同。
这会产生:
>>> di1 = {'Name': 'cat', 'Age': 9,'Alpha':'mat','Beta':'deep'};
>>> di2 = {'Name': 'cat', 'Age': 27,'Alpha':'rat'};
>>> for key, value in di1.viewitems() ^ di2.viewitems():
... print '{!r}: {!r}'.format(key, value)
...
'Alpha': 'rat'
'Alpha': 'mat'
'Beta': 'deep'
'Age': 27
'Age': 9
您只需查看一个或另一个字典中的键即可进一步细化:
print 'Added keys'
for key in di2.viewkeys() - di1.viewkeys():
print '{!r}: {!r}'.format(key, di2[key])
print 'Removed keys'
for key in di1.viewkeys() - di2.viewkeys():
print '{!r}: {!r}'.format(key, di1[key])
print 'Changed keys'
for key in di1.viewkeys() & di2.viewkeys():
if di1[key] != di2[key]:
print '{!r}: {!r} -> {!r}'.format(key, di1[key], di2[key])
这会产生:
>>> print 'Added keys'
Added keys
>>> for key in di2.viewkeys() - di1.viewkeys():
... print '{!r}: {!r}'.format(key, di2[key])
...
>>> print 'Removed keys'
Removed keys
>>> for key in di1.viewkeys() - di2.viewkeys():
... print '{!r}: {!r}'.format(key, di1[key])
...
'Beta': 'deep'
>>> print 'Changed keys'
Changed keys
>>> for key in di1.viewkeys() & di2.viewkeys():
... if di1[key] != di2[key]:
... print '{!r}: {!r} -> {!r}'.format(key, di1[key], di2[key])
...
'Alpha': 'mat' -> 'rat'
'Age': 9 -> 27
答案 1 :(得分:0)
您可以从两个词典创建键的集合并测试其中一个词典中是否缺少它们,或者它们是否不同。
for k in set(di1).union(set(di2)):
if k not in di1:
print k, "missing in di1"
elif k not in di2:
print k, "missing in di2"
elif di1[k] != di2[k]:
print k, ':', di1[k], '->', di2[k]
答案 2 :(得分:0)
执行此操作的一种方法是在两个词典中创建所有密钥的set
,然后使用dict.get
来处理密钥不在其中一个词典中的情况(请注意{{ 1}} - 如果永远不是实际值,你可以使用object() != object()
:
None
使用中:
def compare(d1, d2):
"""Returns a list of keys that have different values."""
return [k for k in set(d1).union(d2)
if d1.get(k, object()) != d2.get(k, object())]
答案 3 :(得分:0)
di1 = {'Name': 'cat', 'Age': 9,'Alpha':'mat','Beta':'deep'}
di2 = {'Name': 'cat', 'Age': 27,'Alpha':'rat', 'currency':'INR'}
# find intersection
intersection=filter(di1.has_key, di2.keys())
keysnotindi2=list(set(di1.keys())-set(intersection))
keysnotindi1=list(set(di2.keys())-set(intersection))
# by looping on keysnotindi2 and keysnotindi1 you can get values of that particular key
答案 4 :(得分:0)
假设您想要一个人类可读的输出,而不是产生一些复杂的数据结构来提供给您的代码的另一部分......
很多时候你可以回到现有的差异库。
我一直使用diff
或图形比较应用程序(Windiff,Winmerge,Kaleidoscope等)执行此操作。
您必须提前按摩数据。对于词典,请使用json.dump(s)(<obj>, sort_keys=True, indent=4)
在纯Python中使用difflib
:
di1 = {'Name': 'cat', 'Age': 9,'Alpha':'mat','Beta':'deep'};
di2 = {'Name': 'cat', 'Age': 27,'Alpha':'rat'};
import difflib
import json
differ = difflib.Differ()
text1 = json.dumps(di1, sort_keys=True, indent=4)
text2 = json.dumps(di2, sort_keys=True, indent=4)
li1 = text1.splitlines()
li2 = text2.splitlines()
diff = differ.compare(li1, li2)
for line in diff:
print(line)
{
- "Age": 9,
? ^
+ "Age": 27,
? ^^
- "Alpha": "mat",
? ^
+ "Alpha": "rat",
? ^
- "Beta": "deep",
"Name": "cat"
}
您甚至可以先使用assert di1 == di2
来确定平等,然后只在AssertionError
上构建大比较内容。
更改 d2 以使嵌套更复杂:
di2 = {'Name': 'cat', 'Age': 27,'Alpha':'rat', "nested" : {"child1":"foo","child2":"bar"}};
给出:
(截断保持不变的位数)
- "Beta": "deep",
- "Name": "cat"
+ "Name": "cat",
? ++
+ "nested": {
+ "child1": "foo",
+ "child2": "bar"
+ }
}