
本文详解如何正确遍历 JSON 解析后的对象列表,安全访问嵌套字段(如 segments 和 rubric),并使用集合交集实现高性能 ID 匹配,避免常见 TypeError 和逻辑错误。
本文详解如何正确遍历 json 解析后的对象列表,安全访问嵌套字段(如 `segments` 和 `rubric`),并使用集合交集实现高性能 id 匹配,避免常见 `typeerror` 和逻辑错误。
在 Python 中处理 JSON 数据时,尤其是从文件或 API 获取的嵌套结构(如包含 segments 数组和 rubric 对象的文档列表),常因字段访问方式不当导致运行时错误或空结果。你遇到的 filtered_data 始终为空,根本原因在于两个关键误用:一是混淆了面向对象的 hasattr() 与字典键存在性检查;二是错误地将列表当作字典索引(item["segments"]["id"])。
首先,json.loads() 返回的是标准 Python 字典(dict)和列表(list)构成的嵌套结构,不是自定义类实例。因此 hasattr(item, "segments") 永远返回 False —— 字典没有属性(attribute),只有键(key)。应改用 "segments" in item 判断键是否存在。
其次,item["segments"] 是一个列表(如 [{"slug": "...", "id": "111111"}, ...]),不能用字符串 "id" 索引。原写法 item["segments"]["id"] 会触发 TypeError: list indices must be integers or slices。正确做法是遍历该列表,提取每个元素的 "id" 字段。
以下是修正后的完整过滤函数(含健壮性增强):
import json
def get_data_from_json(self, json_data, filter_config):
try:
data = json.loads(json_data)
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON format: {e}")
# 预计算过滤所需的集合,提升性能(尤其当数据量大时)
target_segment_ids = set(filter_config.get("segment_ids", []))
target_rubric_ids = set(filter_config.get("rubric_ids", []))
filtered_data = []
for item in data:
# ✅ 安全检查:确保必要键存在且类型正确
if not isinstance(item, dict):
continue
if "segments" not in item or not isinstance(item["segments"], list):
continue
if "rubric" not in item or not isinstance(item["rubric"], dict):
continue
if "id" not in item["rubric"]:
continue
# ✅ 提取 segments 中所有 id 构成集合,并与目标 ID 集合求交集
segment_ids_in_item = {seg.get("id") for seg in item["segments"]
if isinstance(seg, dict) and "id" in seg}
rubric_id = item["rubric"]["id"]
# ✅ 组合所有条件(注意:type 检查放在最后可减少无效计算)
if (segment_ids_in_item & target_segment_ids and
rubric_id in target_rubric_ids and
item.get("type") == "answer"):
filtered_data.append(item)
return filtered_data
关键改进说明:
- 使用
isinstance()和in操作符替代hasattr(),符合字典/列表的实际数据模型; - 用集合交集
&替代any(...)循环,语义清晰且时间复杂度更优(O(1) 平均查找 vs O(n)); - 添加类型校验(如
isinstance(item, dict))和.get("id")防御性编程,避免KeyError或AttributeError; - 将
item.get("type") == "answer"放在条件末尾,利用短路逻辑优先跳过不匹配项,提升效率。
示例调用:
filter_config = {
"segment_ids": ["111111", "999999"],
"rubric_ids": ["123"]
}
result = self.get_data_from_json(json_string, filter_config)
# 返回第一个对象(因其 segments 含 "111111",rubric.id 为 "123",且 type=="answer")
总结:处理嵌套 JSON 数据的核心原则是——始终假设结构可能不完整,用 in 检查键、用 isinstance 校验类型、用集合运算优化匹配。逐步拆解表达式(如先打印 item["segments"] 再调试 seg["id"])是定位问题最有效的方法。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











