如何获取/打印两个字典之间的差异?



我有两个函数必须返回相同的字典(一个是旧方法,另一个是将替换旧方法的新方法)。当我测试新函数给我的结果与旧函数相同时。我正在尝试创建一个程序,它将两个字典作为输入,并验证它们是否具有相同的信息,并告诉我它们之间的任何差异。我的职责是了解新功能的哪些信息是错误的。

这两个字典每次都可以改变。它们的键可以只包含一个字符串或者一个字典或者一个字典列表。此外,这些字典列表可以包含具有字符串值的键,也可以包含字典或另一个字典列表。字典可以任意复杂。

我已经试过了,但是结果不太好。attr_prod是一个返回旧函数的字典示例。attr_test是一个返回new函数的字典示例。

def main():
attr_prod = {
'key1': 'a',
'key2': [ {
'key3': 'n1',
'key4': 'n2',
'key5': [ {
'key6': 'n1',
'key7': 'n2',
'key8': {
'key10': 'g1',
'key11': 'g2',
'key12': 'g3'
}
},
{
'key6': 'n5',
'key7': 'n6',
'key8': {
'key10': 'g4',
'key11': 'g5',
'key12': 'g6'
}
}
]
}
],
'key20': {
'key21': 'g4',
'key22': 'g5',
'key23': 'g6'
}
}
attr_test = {
'key1': 'a',
'key2': [ {
'key3': 'different info',
'key4': 'n2',
'key5': [   {
'key6': 'n1',
'key7': 'n2',
'key8': {
'key10': 'g1',
'key11': 'g2',
'key12': 'g3'
}
},
{
'key6': 'n5',
'key7': 'n6',
'key8': {
'key10': 'different info',
'key11': 'g5',
'key12': 'g6'
}
},
{
'key6': 'this is new',
'key7': 'this is new',
'key8': {
'key10': 'new',
'key11': 'new',
'key12': 'new'
}
}
]
}
],
'key20': {
'key21': 'g4',
'key22': 'different info',
'key23': 'g6'
}
}
for key, value_prod in attr_prod.items():
if isinstance(value_prod, basestring):
check(key, value_prod, attr_test[key])
elif isinstance(value_prod, list):
n_rec = 0
for rec in value_prod:
#                   if isinstance(rec, basestring):
#                       check(key, rec, attr_test[key][n_rec])
print rec
if isinstance(rec, dict):
for key2, value_prod2 in rec.items():
if isinstance(value_prod2, basestring):
check(key, value_prod2, attr_test[key][n_rec][key2])
elif isinstance(value_prod2, list):
n_rec2 = 0
for rec2 in value_prod2:
for key3, value_prod3 in rec2.items():
if isinstance(value_prod3, basestring):
check(key, value_prod3, attr_test[key][n_rec][key2][n_rec2][key3])
n_rec2 += 1
n_rec += 1

def check(key, value_prod, value_test):
if value_test != value_prod:
print "KO key: %s test: -%s- prod: -%s-" % (key, value_test, value_prod)

我建议使用递归字典比较函数作为生成器(从而允许您使用下一个函数有效地检测至少一个差异):

def compareDict(before,after):
for k,old in before.items():
if k not in after: yield f"{k}: deleted";continue
new = after[k]
if type(old) != type(new):
yield f"{k}: changed from: {old}"
yield f"{k}: changed   to: {new}"
elif isinstance(old,dict):
yield from (f"{k}:{change}" for change in compareDict(old,new))
elif isinstance(old,(tuple,list)):
b = {f"[{i}]":v for i,v in enumerate(old)}
a = {f"[{i}]":v for i,v in enumerate(new)}
yield from (f"{k}:{change}" for change in compareDict(b,a))
elif old != new:
yield f"{k}: changed from: {old}"
yield f"{k}: changed   to: {new}"
for k,new in after.items():
if k not in before: yield f"{k}: added: {new}"

输出:

for change in compareDict(attr_prod,attr_test): print(change)
key2:[0]:key3: changed from: n1
key2:[0]:key3: changed   to: different info
key2:[0]:key5:[1]:key8:key10: changed from: g4
key2:[0]:key5:[1]:key8:key10: changed   to: different info
key2:[0]:key5:[2]: added: {'key6': 'this is new', 'key7': 'this is new', 'key8': {'key10': 'new', 'key11': 'new', 'key12': 'new'}}
key20:key22: changed from: g5
key20:key22: changed   to: different info

最新更新