python - 如何获取/打印两个字典之间的差异?
问题描述
我有两个必须返回相同字典的函数(一个是旧方法,另一个是替换旧方法的新方法)。当我测试新函数给我的结果与旧函数相同时。我正在尝试创建一个程序,该程序将两个字典作为输入,并验证它们是否具有相同的信息并告诉我它们之间的任何差异。我的范围是了解新功能的哪些信息是错误的。
这两个字典每次都可以更改。它们可能具有仅包含字符串或字典或字典列表的键。此外,这些字典列表可能包含具有字符串值的键或字典或另一个字典列表。字典可以任意复杂。
我试过这个,但结果并不好。
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',
'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
推荐阅读
- ios - 从 CIIImage iOS swift 转换时如何修复 UIImage 方向
- nginx - grpc_next_upstream 未尝试 2 级代理中的下一个上游服务器
- r - 将 s 曲线添加到 r ggplot
- python - 运行 exe 文件时出现“ModuleNotFoundError”
- ansible - 如何使用 ansible 比较存储在寄存器中的输出
- python - 使用 tf.image.extract_glimpse 的问题
- php - 给定 [c] 邮箱中的地址不符合 RFC 2822、Laravel、Swiftmailer
- pandas - 无法将数据从一个系列附加到熊猫中的其他系列
- apache-kafka - 带有 Json Schema 注册表的 Kafka JDBC 接收器连接器
- javascript - 在加载新数据之前显示旧数据的模式