如何简化Python嵌套字典的存在性检查与元素添加?
优化嵌套字典的存在性检查与元素添加实现
问题描述
我有一个包含字典列表和嵌套字符串列表的字典,目前使用推导式在添加元素前执行存在性检查,但不确定这是否是最优、最简化的实现方式。最终该字典将保存为JSON文件。
现有代码
my_dict = { 'employees':[ { 'name':'Kevin', 'software':[ { 'name':'soft1', 'modules':[ 'mod1', 'mod2', 'mod3' ] }, { 'name':'soft2', 'modules':[ 'mod1', 'mod2', 'mod3' ] }, { 'name':'soft3', 'modules':[ 'mod1', 'mod2', 'mod3' ] } ] }, { 'name':'Bob', 'software':[ { 'name':'soft3', 'modules':[ 'mod4', 'mod5', 'mod6' ] }, { 'name':'soft4', 'modules':[ 'mod10' ] }, { 'name':'soft6', 'modules':[ 'mod1', 'mod5' ] }, { 'name':'soft7', 'modules':[ 'mod1', 'mod3', 'mod5' ] } ] } ] } new_employee_name = "Steward" new_software_learnt = "soft2" new_module_learnt = "mod20" if not new_employee_name in [_['name'] for _ in my_dict['employees']]: my_dict['employees'].append({'name':new_employee_name, 'software':[{"name":new_software_learnt, 'modules':[new_module_learnt]}]}) new_software_learnt = "soft3" new_module_learnt = "mod22" if not new_software_learnt in [_['name'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]]: my_dict['employees'][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]['software'].append({'name':new_software_learnt, 'modules':[new_module_learnt]}) new_software_learnt = "soft3" new_module_learnt = "mod55" if not new_module_learnt in [_['modules'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]][[_['name'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]].index(new_software_learnt)]: [_['modules'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]][[_['name'] for _ in [_['software'] for _ in my_dict['employees']][[_['name'] for _ in my_dict['employees']].index(new_employee_name)]].index(new_software_learnt)].append(new_module_learnt) print(my_dict['employees'])
优化方案
你的现有代码嵌套推导式过多,可读性差且存在大量重复遍历计算,最优方案是拆分出针对每一层的独立查找函数,简化逻辑同时提升效率。
1. 实现分层查找辅助函数
针对员工、软件、模块三层结构,分别编写单一职责的查找函数,避免重复遍历:
def find_employee(employees, name): """查找指定名称的员工字典,不存在则返回None""" for emp in employees: if emp['name'] == name: return emp return None def find_software(employee, software_name): """查找员工下指定名称的软件字典,不存在则返回None""" for soft in employee['software']: if soft['name'] == software_name: return soft return None def has_module(software, module_name): """检查软件是否包含指定模块""" return module_name in software['modules']
2. 重构添加逻辑
使用上述函数重构添加流程,代码逻辑清晰,避免重复计算:
my_dict = { # 原字典内容不变 } new_employee_name = "Steward" new_software_learnt = "soft2" new_module_learnt = "mod20" # 处理员工层:不存在则创建 employee = find_employee(my_dict['employees'], new_employee_name) if not employee: employee = {'name': new_employee_name, 'software': []} my_dict['employees'].append(employee) # 处理软件层:不存在则创建 software = find_software(employee, new_software_learnt) if not software: software = {'name': new_software_learnt, 'modules': []} employee['software'].append(software) # 处理模块层:不存在则添加 if not has_module(software, new_module_learnt): software['modules'].append(new_module_learnt) # 后续添加操作同理 new_software_learnt = "soft3" new_module_learnt = "mod22" software = find_software(employee, new_software_learnt) if not software: software = {'name': new_software_learnt, 'modules': []} employee['software'].append(software) new_module_learnt = "mod55" if not has_module(software, new_module_learnt): software['modules'].append(new_module_learnt) print(my_dict['employees'])
3. 是否需要专用Python模块?
对于你的需求来说,不需要额外模块,原生Python配合自定义函数已经足够轻量高效。如果后续需要更复杂的数据验证、结构化处理,可以考虑pydantic模块,但当前场景下属于过度设计。
4. 拆分函数的优势
- 可读性提升:每个函数只负责单一逻辑,代码结构清晰,易于理解和维护
- 效率优化:避免原代码中多次重复生成推导式和索引查找,单次遍历即可定位目标
- 可复用性:后续添加其他员工、软件或模块时,直接调用函数即可,无需重复编写嵌套推导式
内容的提问来源于stack exchange,提问作者zooid
相关产品推荐
相关产品推荐

