你可以使用递归:
a_standard = {
'section1': {
'category1': 1,
'category2': 2
},
'section2': {
'category1': 1,
'category2': 2
}
}
a_new = {
'section1': {
'category1': 1,
'category2': 2
},
'section2': {
'category1': 1,
'category2': 3
}
}
def differences(a, b, section=None):
return [(c, d, g, section) if all(not isinstance(i, dict) for i in [d, g]) and d != g else None if all(not isinstance(i, dict) for i in [d, g]) and d == g else differences(d, g, c) for [c, d], [h, g] in zip(a.items(), b.items())]
n = filter(None, [i for b in differences(a_standard, a_new) for i in b])
输出:
[('category2', 2, 3, 'section2')]
这会产生对应于不相等值的键。
编辑:没有列表理解:
def differences(a, b, section = None):
for [c, d], [h, g] in zip(a.items(), b.items()):
if not isinstance(d, dict) and not isinstance(g, dict):
if d != g:
yield (c, d, g, section)
else:
for i in differences(d, g, c):
for b in i:
yield b
print(list(differences(a_standard, a_new)))
输出:
['category2', 2, 3, 'section2']
此解决方案使用生成器(因此使用了yield 语句),它即时存储生成的值,只记住它停止的位置。可以通过将返回的结果转换为列表来获取这些值。 yield 使累积值差异变得更容易,并且无需在函数或全局变量中保留额外的参数。