Python嵌套JSON解析:根据UniqueID获取对应value字段值
实现方案
针对高度嵌套、存在重名键的JSON结构,不需要硬编码字段路径,直接做全层级深度遍历匹配目标UniqueID即可,以下是不同场景下可直接复用的实现:
方案1:单次/少量查询场景(递归遍历)
适合查询次数少、不想额外占用内存存储索引的场景,遍历到匹配结果就立刻返回,不会多余遍历后续节点。
import json from typing import Any, Optional def find_value_by_uid(data: Any, target_uid: str) -> Optional[str]: # 当前节点是字典:检查是否匹配目标 if isinstance(data, dict): if data.get("UniqueID") == target_uid and "value" in data: return data["value"] # 遍历字典所有子节点继续查找 for sub_val in data.values(): match_res = find_value_by_uid(sub_val, target_uid) if match_res is not None: return match_res # 当前节点是列表:遍历所有元素继续查找 elif isinstance(data, list): for item in data: match_res = find_value_by_uid(item, target_uid) if match_res is not None: return match_res # 基础类型节点(字符串、数字等)无匹配,直接返回 return None # 调用示例 if __name__ == "__main__": with open("your_data.json", "r", encoding="utf-8") as f: raw_data = json.load(f) print(find_value_by_uid(raw_data, "123456789")) # 输出 korea
如果你的JSON嵌套层级超过Python默认递归深度限制(默认1000层),把递归逻辑换成基于栈的迭代遍历即可,避免栈溢出。
方案2:频繁查询场景(预构建索引)
如果需要反复查询不同UniqueID,每次遍历全量JSON效率太低,第一次加载文件时就把所有UniqueID和对应value的映射提前构建成字典,后续查询时间复杂度为O(1)。
import json from typing import Any, Dict def build_uid_index(data: Any, index_map: Dict[str, str]) -> None: if isinstance(data, dict): current_uid = data.get("UniqueID") if current_uid and "value" in data: # 若存在重复UniqueID的情况,后续遍历到的同ID值会覆盖之前的,需要存多值可改为列表append index_map[current_uid] = data["value"] for sub_val in data.values(): build_uid_index(sub_val, index_map) elif isinstance(data, list): for item in data: build_uid_index(item, index_map) # 调用示例 if __name__ == "__main__": uid_index = {} with open("your_data.json", "r", encoding="utf-8") as f: raw_data = json.load(f) build_uid_index(raw_data, uid_index) # 后续查询直接从索引取即可 print(uid_index.get("123456789")) # 输出 korea print(uid_index.get("987782999")) # 输出 Japan
搭配独立的UniqueID含义映射文件使用
你单独存储的ID含义映射文件如果是JSON格式,直接加载为字典即可和查询结果关联:
# 加载ID含义映射表 with open("uid_desc_map.json", "r", encoding="utf-8") as f: uid_desc = json.load(f) target_uid = "123456789" match_value = uid_index.get(target_uid) match_desc = uid_desc.get(target_uid)
额外优化提示
- 如果JSON文件体积过大(GB级),全量加载内存压力大,可以用
ijson做流式遍历,遍历过程中匹配到目标ID就直接终止读取,不需要把整个文件载入内存。 - 如果业务中存在同一个UniqueID对应多个value的情况,把索引存储结构从单字符串改为列表,匹配到值时追加到列表即可,避免覆盖。
内容的提问来源于stack exchange,提问作者saltpetre
相关产品推荐
相关产品推荐

