现在还有一些不足之处,比如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