Python嵌套列表取值函数异常:无法提取嵌套列表索引路径值
问题:
extract_values_nested函数无法处理嵌套列表元素的索引路径取值 我编写的extract_values_nested函数能够正常处理单层键路径和列表内嵌套字典路径的取值,但无法处理嵌套列表元素的索引路径取值。以下是示例数据、代码、测试用例及当前输出:
示例数据
data = [ { "rate_id": 174596, "rate_code": "ACE", "room_types": [ { "id": 1450, "name": "Queenn", }, { "id": 1451, "name": "King", } ] }, { "rate_id": 174340, "rate_code": "DFD", "cancel_rule_info": {"a":5}, "room_types": [ { "id": 1452, "name": "Suite", } ] } ]
原函数代码
from typing import List, Any def extract_values_nested(data: List[dict], key_path: str) -> List[Any]: """ 从字典列表中根据嵌套键路径提取对应值。 参数: data (List[dict]): 字典组成的列表。 key_path (str): 要搜索的嵌套键路径。 返回: List[Any]: 指定嵌套键路径对应的所有值组成的列表。 """ keys = key_path.split('.') results = [] def extract_recursive(subdata, keys): if isinstance(subdata, list): for item in subdata: extract_recursive(item, keys) elif isinstance(subdata, dict): key = keys[0] if key.isdigit(): key = int(key) if key in subdata: if len(keys) == 1: results.append(subdata[key]) else: extract_recursive(subdata[key], keys[1:]) for entry in data: extract_recursive(entry, keys) return results
测试用例
print(extract_values_nested(data, "room_types.0.id")) print(extract_values_nested(data, "room_types")) print(extract_values_nested(data, "rate_code")) print(extract_values_nested(data, "cancel_rule_info.a"))
当前输出
[] [[{'id': 1450, 'name': 'Queenn'}, {'id': 1451, 'name': 'King'}], [{'id': 1452, 'name': 'Suite'}]] ['ACE', 'DFD'] [5]
可以看到,除第一个测试用例返回空列表外,其余输出均符合预期。
修复方案
原函数的问题在于处理列表类型数据时,直接遍历所有元素并传入完整键路径,没有考虑当前键可能是列表索引的情况。修改后的函数会区分列表索引和普通键的处理逻辑:
修改后的函数代码
from typing import List, Any def extract_values_nested(data: List[dict], key_path: str) -> List[Any]: """ 从字典列表中根据嵌套键路径提取对应值。 参数: data (List[dict]): 字典组成的列表。 key_path (str): 要搜索的嵌套键路径。 返回: List[Any]: 指定嵌套键路径对应的所有值组成的列表。 """ keys = key_path.split('.') results = [] def extract_recursive(subdata, keys): if not keys: results.append(subdata) return current_key = keys[0] remaining_keys = keys[1:] if isinstance(subdata, list): if current_key.isdigit(): # 处理列表索引,定位到对应元素后递归处理剩余路径 idx = int(current_key) if 0 <= idx < len(subdata): extract_recursive(subdata[idx], remaining_keys) else: # 非索引则遍历所有列表元素,继续处理完整键路径 for item in subdata: extract_recursive(item, keys) elif isinstance(subdata, dict): if current_key in subdata: extract_recursive(subdata[current_key], remaining_keys) for entry in data: extract_recursive(entry, keys) return results
修复后测试输出
[1450, 1452] [[{'id': 1450, 'name': 'Queenn'}, {'id': 1451, 'name': 'King'}], [{'id': 1452, 'name': 'Suite'}]] ['ACE', 'DFD'] [5]
修复说明
- 新增
if not keys判断:当键路径耗尽时,直接将当前数据加入结果列表 - 列表处理逻辑拆分:
- 若当前键是数字索引,直接定位到列表对应元素,递归处理剩余键路径
- 若不是索引,遍历所有列表元素并继续处理完整键路径
- 简化字典处理逻辑,去掉冗余的键类型判断,直接检查键存在性后递归
内容的提问来源于stack exchange,提问作者A l w a y s S u n n y
相关产品推荐
相关产品推荐

