非结构化姓名数据转嵌套字典:优化迭代状态记忆的方法
优化方案:线性迭代+状态预判的简洁实现
我们可以用迭代器主动遍历+直接预判后续元素的思路,替代依赖previous变量的回溯式判断,让逻辑更线性、更易读,同时减少冗余分支。
优化后的完整代码
import re from collections import defaultdict def fix_demographic(info): # 整合年龄转换逻辑到这里,让主函数更简洁 race, gender, age = re.split(r'\s*/\s*', re.sub(r'\?+', 'NaN', info)) return race, gender, int(age) if age.isnumeric() else age def parse_victim_info(info: list): res = defaultdict(dict) info_iter = iter(info) while True: try: current_item = next(info_iter) # 判断当前元素是否为姓名:既不是OFFICER,也不是人口统计格式 if not re.fullmatch(r'(\w+|\?+)\s*\/\s*(\w+|\?+)\s*\/\s*(\w+|\?+)', current_item) and current_item.lower() != 'officer': current_name = current_item # 主动获取下一个元素,判断是否是OFFICER标记 next_item = next(info_iter) if next_item.lower() == 'officer': is_officer = True # 再取下一个元素,就是人口统计信息 demo_info = next(info_iter) else: is_officer = False demo_info = next_item # 处理人口统计信息并填充结果字典 race, gender, age = fix_demographic(demo_info) res[current_name] = { 'race': race, 'gender': gender, 'age': age, 'officer': is_officer } except StopIteration: # 迭代器耗尽,退出循环 break # 转换为普通字典返回(可选,根据需求) return dict(res)
思路说明
- 迭代器主动遍历:把列表转为迭代器后,我们可以主动调用
next()获取后续元素,避免用previous变量记录状态,逻辑更直接。 - 一次性分组判断:拿到姓名后,直接检查下一个元素是
OFFICER还是人口统计信息,一次性完成二元组/三元组的识别,避免分散的条件判断。 - 逻辑聚合:把两种格式的处理逻辑合并,减少重复代码,同时把年龄转换逻辑整合到
fix_demographic中,让主函数更简洁。
测试验证
运行以下代码:
info = [ 'Joe Schmoe', 'W / M / 64', 'Richard Johnson', 'OFFICER', 'W / M /48', 'Adrian Stevens', '? / ? / 27' ] result = parse_victim_info(info) print(result)
输出与预期完全一致:
{ 'Joe Schmoe': {'race': 'W', 'gender': 'M', 'age': 64, 'officer': False}, 'Richard Johnson': {'race': 'W', 'gender': 'M', 'age': 48, 'officer': True}, 'Adrian Stevens': {'race': 'NaN', 'gender': 'NaN', 'age': 27, 'officer': False} }
内容的提问来源于stack exchange,提问作者Brad Solomon
相关产品推荐
相关产品推荐

