
本文详解如何处理含多层嵌套与列表结构的json响应,重点解决因误将列表当作字典访问而导致的typeerror,并提供健壮、可扩展的提取方案。
本文详解如何处理含多层嵌套与列表结构的json响应,重点解决因误将列表当作字典访问而导致的typeerror,并提供健壮、可扩展的提取方案。
从错误信息 TypeError: list indices must be integers, not str 可以明确看出:代码试图用字符串键(如 "generationmix")直接索引一个列表对象,而列表只支持整数下标访问。观察实际JSON结构可知,grid_data["data"] 是一个列表(包含区域数据),其首项([0])是一个字典;该字典内又有 "data" 字段,它再次是一个列表(含时间片数据),其首项([0])才包含 "generationmix" 字段——而该字段本身又是一个燃料类型列表,每个元素是形如 {"fuel": "coal", "perc": 0} 的字典。
因此,原代码 grid_data["data"]["generationmix"]["fuel"]["coal"] 存在三重逻辑错误:
- grid_data["data"] 是列表 → 必须用 [0] 访问;
- grid_data["data"][0]["data"] 仍是列表 → 需再次用 [0];
- "generationmix" 是列表,不是字典 → 无法用 ["fuel"] 直接索引,必须遍历查找。
✅ 正确做法是逐层解包并安全遍历:
import requests
import json
response = requests.get(grid_url)
grid_data = response.json() # 推荐直接使用 .json() 方法,比 json.loads(response.text) 更简洁安全
# 安全提取 coal 的 perc 值(带错误处理)
try:
# 两层列表索引:region → time-slice
generation_mix = grid_data["data"][0]["data"][0]["generationmix"]
# 遍历燃料列表查找 coal
coal_entry = next((f for f in generation_mix if f.get("fuel") == "coal"), None)
if coal_entry:
coal_percentage = coal_entry["perc"]
print(f"coal = {coal_percentage}%")
else:
print("Warning: 'coal' fuel not found in generation mix")
except (KeyError, IndexError, TypeError) as e:
print(f"Failed to extract coal data: {e}")
? 关键注意事项:
- ✅ 始终检查JSON结构:使用 print(type(obj)) 或 pprint.pprint(grid_data) 快速确认字段类型(list vs dict);
- ✅ 优先使用 response.json() 而非 json.loads(response.text),它自动处理编码并抛出更清晰的异常;
- ✅ 使用 next(..., default) 和 .get() 提高鲁棒性,避免 KeyError;
- ✅ 若需提取多个燃料(如 gas, wind),建议构建映射字典:fuel_map = {f["fuel"]: f["perc"] for f in generation_mix};
- ⚠️ 不要假设列表非空——生产环境应添加 if grid_data["data"]: 等存在性校验。
通过理解JSON中字典与列表的混合嵌套模式,并采用结构化遍历而非硬编码路径,即可稳定、可维护地提取任意层级的字段。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











