文章目录

  • 前言
  • 一、使用目的和设计思路
  • 二、使用步骤
  • 1.python3环境代码
  • 2.字典对比的打印结果
  • 总结



前言

在工作中或者某些场景,我们需要去对比两个字典对象的差异性。尤其是软件版本升级的时候我们需要去验证一些API接口返回的数据,升级前后数据是否一致,如果不一致,则需要打印出这些不一致的地方,人工或者代码去判断是否满足功能要求。


一、使用目的和设计思路

例如现在有两个字典dict1和dict2,我要找出这两个字典之间的差异。

dict1 = {'name':'古天乐','age':26,'cars': {'BMW':['740','X5'],'Audi':'A8','Porsche':['Cayenne']},'爱好':['射击','足球'],'city':'WUH','school':'DMT'}

dict2 = {'name':'古天乐','age':27,'cars':{'BMW':['740','X3','535Li']},'爱好':['射击','篮球'],'cityname':'WUH'}

这两个字典的结构稍微偏复杂,里面嵌套了列表和字典,这种嵌套结构的数据在API接口中很常见。现在我们想要对这两个字典进行对比,我们期望得到如下对比结果:

1)dict1中有而dict2中缺失的key;dict2中有而dict1中缺失的key

2)dict1和dict2中嵌套的列表中缺失的元素

3)dict1和dict2中相同key却不同值的差异打印

4)如上的打印,都需要打印出字典中key的绝对路径

二、使用步骤

1.python3环境代码

代码如下:

dict1 = {'name':'古天乐','age':26,'cars': {'BMW':['740','X5'],'Audi':'A8','Porsche':['Cayenne']},'爱好':['射击','足球'],'city':'WUH','school':'DMT'}
dict2 = {'name':'古天乐','age':27,'cars':{'BMW':['740','X3','535Li']},'爱好':['射击','篮球'],'cityname':'WUH'}

class CompareHandle():
    def __init__(self):
        pass

    def compareDictionaries(self,dict1:dict,dict2:dict,path=''):
        err = ''
        key_err = ''
        value_err = ''
        listValue_err = ''
        oldpath = path

        for k in dict1.keys():
            if oldpath != '':
                path = f'{oldpath}->{k}'
            else:
                path = f'{k}'
            if k not in dict2:
                key_err += f'{path}:该key在dict2中缺失\n'
            else:
                if isinstance(dict1[k],dict) and isinstance(dict2[k],dict):
                    err += self.compareDictionaries(dict1[k],dict2[k],path)
                else:
                    if dict1[k] != dict2[k]:
                        if isinstance(dict1[k],list) and isinstance(dict2[k],list):
                            if isinstance(dict1[k][0],str): #暂时只考虑list中对象全为str的情况
                                diffList1 = list(set(dict1[k])-set(dict2[k]))
                                diffList2 = list(set(dict2[k]) - set(dict1[k]))
                                if diffList1 != [] and diffList2 == []:
                                    listValue_err += f'{path}:{diffList1}该元素在ditc2中缺失\n'
                                elif diffList1 == [] and diffList2 != []:
                                    listValue_err += f'{path}:{diffList2}该元素在ditc1中缺失\n'
                                else:
                                    listValue_err += f'{path}:{diffList1}该元素在ditc2中缺失\n'
                                    listValue_err += f'{path}:{diffList2}该元素在ditc1中缺失\n'
                                    # print(key_err)
                        else:
                            value_err += f'{path}:\n'
                            value_err += f'\t- {dict1[k]}\n'
                            value_err += f'\t- {dict2[k]}\n'
        for k in dict2.keys():
            if oldpath != '':
                path = f'{oldpath}->{k}'
            else:
                path = f'{k}'
            if k not in dict1:
                key_err += f'{path}:该key在dict1中缺失\n'

        return key_err + value_err + err + listValue_err

compareHandle = CompareHandle()
ret = compareHandle.compareDictionaries(dict1,dict2)
print(ret)

2.字典对比的结果打印

city:该key在dict2中缺失
school:该key在dict2中缺失
cityname:该key在dict1中缺失
age:
	- 26
	- 27
cars->Audi:该key在dict2中缺失
cars->Porsche:该key在dict2中缺失
cars->BMW:['X5']该元素在ditc2中缺失
cars->BMW:['X3', '535Li']该元素在ditc1中缺失
爱好:['足球']该元素在ditc2中缺失
爱好:['篮球']该元素在ditc1中缺失

总结

可以很好的对比出两个字典的差异,运用到工作中则能对应实现对比两份json数据的差异。只是目前代码中对于嵌套列表,列表只支持元素全是字符串的情况。欢迎大家提出意见!