微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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

这两个词典每次都可以更改。它们可以具有仅包含字符串或字典或字典列表的键。此外,这些字典列表可以包含具有字符串值或字典或其他字典列表的键。字典可以任意复杂。

我试过这个,但结果不好。 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 举报,一经查实,本站将立刻删除。