我有两本词典
a = {'home': {'name': 'Team1', 'score': 0}, 'away': {'name': 'Team2', 'score': 0}}
b = {'home': {'name': 'Team1', 'score': 2}, 'away': {'name': 'Team2', 'score': 0}}
密钥永远不会改变,但我想让['home'] ['得分']改变
这么简单吗?
答案 0 :(得分: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']
答案 1 :(得分: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"]}
答案 2 :(得分: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 :(得分:0)
我不确定这是否是你需要的,但是我发现了一个在python数据结构之间产生差异的库。它被称为datadiff,它可以让你了解两个字典之间的所有不同之处。我不确定是否会给你“商店”的差异,也许它会为整个“家”条目显示不同的价值。你必须尝试一下。