【Python】对比嵌套JSON的不同
前言
此对比默认json arry中的顺序相同,在Python中即list中出现的顺序相同。将结果保存在对应的xx_ret中。
import json
import os
import string
# 保存不同的字段
different_ret = []
# 保存缺失的字段
lack_ret = []
# 保存额外的字段
extra_ret = []
# 保存do_check对比时baseJson的前缀
base_json_pre_list = []
# 保存遍历多余字段的前缀
extra_pre_list = []
def do_check(jsonBase,json2):
# 保证它们是同一种类型
if isinstance(json2,dict):
# 思必驰格式判断
if not isinstance(jsonBase, dict):
different_ret.append("格式错误")
return
for key_c,value_c in json2.items():
if key_c == "conf" or key_c == "score":
continue
base_json_pre_list.append('['+"\""+key_c+"\""+']')
# TODO: 更复杂的嵌套情况没有仔细想,但是应该不影响
if key_c in jsonBase:
tmp_aispeech_json = jsonBase[key_c]
jsonBase["OC_" + key_c] = jsonBase.pop(key_c)
# 判断value是否需要继续递归
if isinstance(value_c, list) or isinstance(value_c, dict):
do_check(tmp_aispeech_json, value_c)
jsonBase["OC_" + key_c] = tmp_aispeech_json
continue
# 无需继续递归,直接对比
# 对比value
if value_c != jsonBase["OC_" + key_c]:
# TODO: 收集不同的
different_ret.append(''.join(base_json_pre_list))
else:
# TODO: 收集缺少的
lack_ret.append(''.join(base_json_pre_list))
continue
base_json_pre_list.pop()
elif isinstance(json2,list):
if not isinstance(jsonBase,list):
different_ret.append("格式错误")
return
for item_c_i in range(len(json2)):
if item_c_i >= len(jsonBase):
lack_ret.append('['+str(item_c_i)+']')
return
base_json_pre_list.append('['+str(item_c_i)+']')
do_check(jsonBase[item_c_i],json2[item_c_i])
base_json_pre_list.pop()
# 检查额外的字段
def do_check_extra(json_object):
if isinstance(json_object,dict):
for key,value in json_object.items():
extra_pre_list.append('['+"\""+key+"\""+']')
if not isinstance(value,list) and not isinstance(value,dict): # v为string
# 判断key是否被标记过,没有则保存
if not "OC_" in key:
tmp_save_str = ''.join(extra_pre_list)
tmp_save_str = tmp_save_str.replace("OC_","")
extra_ret.append(tmp_save_str)
else:
do_check_extra(value)
extra_pre_list.pop()
elif isinstance(json_object,list):
for item_i in range(len(json_object)):
# 为了保存前缀,这里需要记录索引
extra_pre_list.append('['+str(item_i)+']')
do_check_extra(json_object[item_i])
extra_pre_list.pop()