现在还有一些不足之处,比如list往下深挖的时候,没有再根据不同type来递归了。而且整个方法感觉还可以写的更通用,可以根据不同数据类型来递归。但是在方法里写有点麻烦,有时间写成类,再好好考虑怎么更好的实现。
.py
def compare_dict(a: dict, b: dict, path='', is_ignore_list_sq = False, is_print = True) -> bool:
"""
对比字典,打印不同之处
:param a: 对比字典1
:param b: 对比字典2
:param path: 不用传
:param is_ignore_list_sq: 是否忽略list顺序
:param is_print: 是否打印不同之处
:return: 对比结果
"""
def _print(str):
if is_print:
print(str)
def _path(_key):
if isinstance(_key, int):
return f'{path}[{_key}]'
return f'{path}["{_key}"]'
flag = True
for key in a.keys() - b.keys():
_print(f'a{path} 有额外键值对 a{_path(key)}: {a[key]}')
for key in b.keys() - a.keys():
_print(f'b{path} 有额外键值对 b{_path(key)}: {b[key]}')
for key in a.keys() & b.keys():
if isinstance(a[key], type(b[key])):
if a[key] == b[key]:
pass
else:
flag = False
if isinstance(a[key], (str, int)):
_print(f'a{_path(key)} 和 b{_path(key)} 值不一致 a{_path(key)}: {a[key]}, b{_path(key)}: {b[key]}')
elif isinstance(a[key], (list, tuple, set)):
if is_ignore_list_sq:
for _key in type(a[key])(set(a[key]).difference(set(b[key]))):
_print(f'a{path} 有额外元素 a{_path(key)}: {_key}')
for _key in type(b[key])(set(b[key]).difference(set(a[key]))):
_print(f'b{path} 有额外元素 b{_path(key)}: {_key}')
else:
if len(a[key]) == len(b[key]):
for i in range(len(a[key])):
if a[key][i] == b[key][i]:
pass
else:
compare_dict({i: a[key][i]}, {i: b[key][i]}, f'{_path(key)}', is_ignore_list_sq, is_print)
else:
_print(f'a{_path(key)} 和 b{_path(key)} 元素数量不一致 len(a{_path(key)}): {len(a[key])}, len(b{_path(key)}): {len(b[key])}')
elif isinstance(a[key], dict):
compare_dict(a[key], b[key], f'{_path(key)}', is_ignore_list_sq, is_print)
else:
_print(f'a{_path(key)}: {type(a[key])} 未知格式')
else:
_print(
f'a{_path(key)}: {type(a[key])} 和 b{_path(key)}: {type(b[key])} 数据类型不一致, a{_path(key)}: {a[key]}, b{_path(key)}: {b[key]}')
return flag
if __name__ == '__main__':
a = {"Alex Morgan":{"array":["Super Mario Bros.\"eu","Spider-Man"],"string":"some string","int":2,"aboolean":True,"boolean":True,"object":{"foo":"bar","object1":{"new prop1":"new prop value"},"object2":{"new prop1":"new prop value"},"object3":{"new prop1":"new prop value"},"object4":{"new prop1":"new prop value"}}},"Coco Gauff":{"one":"Monte Carlo","two":"The Fencer"},"Jennifer Lawrence":["The Hunger Games","Red Sparrow"],"California":["San Diego","San Jose"],"John Cena":["F9","Blockers"],"Leonardo DiCaprio":None}
b = {"Alex Morgan":{"array":["Super Mario Bros.","Spider-Man"],"string":"some string","int":"2","otherint":4,"aboolean":"True","boolean":False,"object":{"foo":"bar"}},"Coco Gauff":["Monte Carlo","The Fencer"],"Jennifer Lawrence":["Red Sparrow","The Hunger Games","Passengers","Mother!"],"California":["San Diego","San Jose"],"John Ce*a":["F9","Blockers"],"Alphabet":["Google","Nest","Calico"]}
compare_dict(a, b)
console
a 有额外键值对 a["Leonardo DiCaprio"]: None
a 有额外键值对 a["John Cena"]: ['F9', 'Blockers']
b 有额外键值对 b["John Ce*a"]: ['F9', 'Blockers']
b 有额外键值对 b["Alphabet"]: ['Google', 'Nest', 'Calico']
a["Coco Gauff"]: <class 'dict'> 和 b["Coco Gauff"]: <class 'list'> 数据类型不一致, a["Coco Gauff"]: {'one': 'Monte Carlo', 'two': 'The Fencer'}, b["Coco Gauff"]: ['Monte Carlo', 'The Fencer']
b["Alex Morgan"] 有额外键值对 b["Alex Morgan"]["otherint"]: 4
a["Alex Morgan"]["aboolean"]: <class 'bool'> 和 b["Alex Morgan"]["aboolean"]: <class 'str'> 数据类型不一致, a["Alex Morgan"]["aboolean"]: True, b["Alex Morgan"]["aboolean"]: True
a["Alex Morgan"]["int"]: <class 'int'> 和 b["Alex Morgan"]["int"]: <class 'str'> 数据类型不一致, a["Alex Morgan"]["int"]: 2, b["Alex Morgan"]["int"]: 2
a["Alex Morgan"]["object"] 有额外键值对 a["Alex Morgan"]["object"]["object2"]: {'new prop1': 'new prop value'}
a["Alex Morgan"]["object"] 有额外键值对 a["Alex Morgan"]["object"]["object3"]: {'new prop1': 'new prop value'}
a["Alex Morgan"]["object"] 有额外键值对 a["Alex Morgan"]["object"]["object4"]: {'new prop1': 'new prop value'}
a["Alex Morgan"]["object"] 有额外键值对 a["Alex Morgan"]["object"]["object1"]: {'new prop1': 'new prop value'}
a["Alex Morgan"]["array"][0] 和 b["Alex Morgan"]["array"][0] 值不一致 a["Alex Morgan"]["array"][0]: Super Mario Bros."eu, b["Alex Morgan"]["array"][0]: Super Mario Bros.
a["Alex Morgan"]["boolean"] 和 b["Alex Morgan"]["boolean"] 值不一致 a["Alex Morgan"]["boolean"]: True, b["Alex Morgan"]["boolean"]: False
a["Jennifer Lawrence"] 和 b["Jennifer Lawrence"] 元素数量不一致 len(a["Jennifer Lawrence"]): 2, len(b["Jennifer Lawrence"]): 4