含重复键的JSON文件处理与验证技术问题求助
处理JSON重复键并自动重命名的解决方案
核心思路
标准JSON库的json.load()会直接覆盖重复键且不报错,逐行用json.loads()又因JSON常跨多行导致误判。解决关键是保留所有键的原始出现顺序,不能依赖默认解析逻辑,得用能捕获所有键值对的工具或自定义钩子。
实用方案与代码示例
方案1:自定义解码器(轻量,适合小文件)
直接继承标准库的JSONDecoder,重写object_pairs_hook——这个钩子能拿到所有键值对的原始列表(包括重复项),在里面处理重命名逻辑:
import json def handle_duplicate_keys(pairs, target_key="port"): result = {} key_count = {} for key, val in pairs: if key == target_key: # 给重复的port计数,重命名为port0、port1... cnt = key_count.get(key, 0) new_key = f"{key}{cnt}" result[new_key] = val key_count[key] += 1 else: # 非目标键直接保留,若需处理所有重复键,去掉此判断即可 result[key] = val return result # 自定义解码器类 class DuplicateKeyFixer(json.JSONDecoder): def __init__(self, target_key="port", **kwargs): super().__init__(object_pairs_hook=lambda pairs: handle_duplicate_keys(pairs, target_key), **kwargs) # 使用示例 with open("your_json_file.json", "r", encoding="utf-8") as f: fixed_data = json.load(f, cls=DuplicateKeyFixer) print(fixed_data)
方案2:用ijson流式解析(适合大文件)
如果JSON文件体积过大,加载到内存会占用过多资源,就用ijson逐token解析,既能精准捕获每个键的出现,还能定位重复键的具体位置:
先安装依赖:pip install ijson
import ijson def process_large_json(file_path, target_key="port"): final_data = {} current_obj = None current_key = None key_counter = {target_key: 0} parent_stack = [] with open(file_path, "rb") as f: for prefix, event, value in ijson.parse(f): if event == "start_map": # 进入新对象,记录上下文 new_obj = {} if not parent_stack: current_obj = final_data else: parent_obj = parent_stack[-1] parent_obj[current_key] = new_obj parent_stack.append(new_obj) elif event == "end_map": # 退出当前对象 parent_stack.pop() current_obj = parent_stack[-1] if parent_stack else None elif event == "map_key": # 处理键,重复的target_key重命名 current_key = value if value == target_key: current_key = f"{target_key}{key_counter[target_key]}" key_counter[target_key] += 1 elif event in ("string", "number", "boolean", "null") and current_obj is not None: # 给当前对象赋值 current_obj[current_key] = value return final_data # 使用示例 fixed_large_data = process_large_json("big_json_file.json") print(fixed_large_data)
额外提示
- 若需处理所有重复键(不止port),去掉代码中
target_key的判断逻辑,改为对所有键统一计数即可。 - 逐行验证误判的问题:JSON对象通常跨多行,逐行解析自然会报错,应按完整JSON对象解析,上述流式方案可定位到包含重复键的具体对象。
内容的提问来源于stack exchange,提问作者CandleWax
相关产品推荐
相关产品推荐

