如何修改deep_get函数以支持嵌套字典中的列表索引访问
让deep_get函数支持嵌套字典与列表索引访问
原函数的局限
原定义的deep_get函数仅能处理纯嵌套字典的取值,当路径中包含列表索引(如person.names[0])时无法正确解析,会返回None。
原函数代码:
from functools import reduce def deep_get(dictionary, keys, default=None): return reduce( lambda d, key: d.get(key, default) if isinstance(d, dict) else default, keys.split("."), dictionary, )
测试示例及问题:
person1 = {'person': {'name': {'first': 'John'}}} print(deep_get(person1, "person.name.first")) # 输出 John person2 = {'person': {'names': ['Adam', 'John']}} print(deep_get(person2, "person.names")) # 输出 ['Adam', 'John'] print(deep_get(person2, "person.names[0]")) # 输出 None(不符合预期,期望返回Adam)
修改方案
要支持列表索引,需要先解析路径中的索引部分,将类似names[0]的节点拆分为键名names和索引0,然后分别处理字典取值和列表索引访问。
修改后的函数代码:
from functools import reduce import re def deep_get(dictionary, keys, default=None): # 正则匹配路径节点,提取键名和可选的数字索引 key_parser = re.compile(r'(\w+)(?:\[(\d+)\])?') def traverse(current, key_segment): match = key_parser.fullmatch(key_segment) if not match: return default key, idx_str = match.groups() # 先处理字典键取值 if isinstance(current, dict): current = current.get(key, default) # 如果当前值是列表且存在索引,尝试访问索引 if idx_str is not None and isinstance(current, list): try: current = current[int(idx_str)] except (IndexError, ValueError): return default # 处理当前为列表且节点是纯索引的情况(如路径为"list[1]") elif idx_str is not None and isinstance(current, list): try: current = current[int(idx_str)] except (IndexError, ValueError): return default else: # 非字典/可索引列表,返回默认值 return default return current if current is not default else default # 按点分割路径后逐个处理节点 return reduce(traverse, keys.split("."), dictionary)
测试验证
运行以下代码验证效果:
person1 = {'person': {'name': {'first': 'John'}}} print(deep_get(person1, "person.name.first")) # 输出 John person2 = {'person': {'names': ['Adam', 'John']}} print(deep_get(person2, "person.names")) # 输出 ['Adam', 'John'] print(deep_get(person2, "person.names[0]")) # 输出 Adam print(deep_get(person2, "person.names[1]")) # 输出 John print(deep_get(person2, "person.names[2]")) # 输出 None(索引越界,返回默认值)
关键改进点
- 用正则表达式拆分路径节点,识别字典键和列表索引的组合格式
- 对列表索引访问添加异常捕获,处理索引越界、非数字索引等异常情况,返回预设默认值
- 兼容原有的纯字典路径取值逻辑,不破坏原有功能
内容的提问来源于stack exchange,提问作者pingwin850
相关产品推荐
相关产品推荐

