如何解决如何获取/打印两个字典之间的差异?
我有两个函数必须返回相同的字典(一个是旧方法,另一个是将替换旧方法的新方法)。因为我正在测试新函数给我的结果与旧函数相同。我正在尝试创建一个程序,该程序将两个字典作为输入,并验证它们是否具有相同的信息并告诉我它们之间的任何差异。我的范围是了解新函数的哪些信息是错误的。
这两个词典每次都可以更改。它们可以具有仅包含字符串或字典或字典列表的键。此外,这些字典列表可以包含具有字符串值或字典或其他字典列表的键。字典可以任意复杂。
我试过这个,但结果不好。
attr_prod
是返回旧函数的字典示例。
attr_test
是返回新函数的字典示例。
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','key5': [ {
'key6': 'n1','key8': {
'key10': 'different info','key12': 'g6'
}
},{
'key6': 'this is new','key7': 'this is new','key8': {
'key10': 'new','key11': 'new','key12': 'new'
}
}
]
}
],'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_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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。