在Python中比较多维字典
我有两个字典
a = {'home': {'name': 'Team1', 'score': 0}, 'away': {'name': 'Team2', 'score': 0}}
b = {'home': {'name': 'Team1', 'score': 2}, 'away': {'name': 'Team2', 'score': 0}}
这些字典的键是不会变的,但我想知道 ['home']['score'] 这个值有没有变化
有没有简单的方法可以做到这一点?
4 个回答
1
这里有一个非常简单的解决方案。它会返回一个列表,里面包含所有不同元素的第一层和第二层字典的键。希望这正是你想要的 :)
a = {'home':{'name': 'Team1', 'score': 0}, 'away':{'name': 'Team2', 'score': 0}}
b = {'home':{'name': 'Team1', 'score': 2}, 'away':{'name': 'Team2', 'score': 0}}
diffs = []
for i in a:
for j in a[i]:
if a[i][j] != b[i][j]:
diffs += [i, j]
print diffs
谢谢!
3
你可以使用我为Python准备的这个包:
https://github.com/seperman/deepdiff
这个包不仅仅处理递归字典之间的差异:
安装
可以从PyPi安装:
pip install deepdiff
如果你使用的是Python3,还需要安装:
pip install future six
示例用法
>>> from deepdiff import DeepDiff
>>> from pprint import pprint
>>> from __future__ import print_function
相同的对象返回空值
>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = t1
>>> ddiff = DeepDiff(t1, t2)
>>> print (ddiff.changes)
{}
某个项目的类型发生了变化
>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:"2", 3:3}
>>> ddiff = DeepDiff(t1, t2)
>>> print (ddiff.changes)
{'type_changes': ["root[2]: 2=<type 'int'> vs. 2=<type 'str'>"]}
某个项目的值发生了变化
>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:4, 3:3}
>>> ddiff = DeepDiff(t1, t2)
>>> print (ddiff.changes)
{'values_changed': ['root[2]: 2 ====>> 4']}
项目被添加或移除
>>> t1 = {1:1, 2:2, 3:3, 4:4}
>>> t2 = {1:1, 2:4, 3:3, 5:5, 6:6}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes)
{'dic_item_added': ['root[5, 6]'],
'dic_item_removed': ['root[4]'],
'values_changed': ['root[2]: 2 ====>> 4']}
字符串之间的差异
>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world"}}
>>> t2 = {1:1, 2:4, 3:3, 4:{"a":"hello", "b":"world!"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes, indent = 2)
{ 'values_changed': [ 'root[2]: 2 ====>> 4',
"root[4]['b']:\n--- \n+++ \n@@ -1 +1 @@\n-world\n+world!"]}
>>>
>>> print (ddiff.changes['values_changed'][1])
root[4]['b']:
---
+++
@@ -1 +1 @@
-world
+world!
字符串之间的差异 2
>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world!\nGoodbye!\n1\n2\nEnd"}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n1\n2\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes, indent = 2)
{ 'values_changed': [ "root[4]['b']:\n--- \n+++ \n@@ -1,5 +1,4 @@\n-world!\n-Goodbye!\n+world\n 1\n 2\n End"]}
>>>
>>> print (ddiff.changes['values_changed'][0])
root[4]['b']:
---
+++
@@ -1,5 +1,4 @@
-world!
-Goodbye!
+world
1
2
End
类型变化
>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n\n\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes, indent = 2)
{ 'type_changes': [ "root[4]['b']: [1, 2, 3]=<type 'list'> vs. world\n\n\nEnd=<type 'str'>"]}
列表之间的差异
>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes, indent = 2)
{ 'list_removed': ["root[4]['b']: [3]"]}
列表之间的差异 2:注意,这里不考虑顺序
>>> # Note that it DOES NOT take order into account
... t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes, indent = 2)
{ }
包含字典的列表:
>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:1, 2:2}]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:3}]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff.changes, indent = 2)
{ 'dic_item_removed': ["root[4]['b'][2][2]"],
'values_changed': ["root[4]['b'][2][1]: 1 ====>> 3"]}
4
作为一个本能的初步反应:
a = {'home': {'name': 'Team1', 'score': 0}, 'away': {'name': 'Team2', 'score': 0}}
b = {'home': {'name': 'Team1', 'score': 2}, 'away': {'name': 'Team2', 'score': 0}}
def valchange(d1, d2, parent=''):
changes=[]
for k in d1.keys():
if type(d1[k])==type({}):
changes.extend(valchange(d1[k], d2[k], k))
else:
if d1[k]!=d2[k]:
if parent=='':
changes.append(k + ' has changed ')
else:
changes.append(parent + '.' + k + ' has changed')
return changes
print valchange(a,b)
>>>
['home.score has changed']