Python排序JSON顶层及二级键值合并文件时KeyError问题求解
报错原因
运行时触发KeyError: 'edition'的核心原因有两点:
- 你写的
d['edition']默认所有待处理JSON的顶层都存在edition键,但你明确说明edition是二级层级的字段,顶层自然找不到这个键,直接访问就会触发键不存在报错。 - 你用的
new_d.update(d['edition'])逻辑本身不符合需求:这个语法要求d['edition']本身是字典类型,执行后会把该字典下的所有子键平铺到new_d的顶层,根本不会把edition作为独立顶层键保留,就算你真的在顶层找到了edition字段,后续排序时依然找不到顶层的edition键,还是会触发报错。
另外原代码还有两个隐性问题:
- 把函数定义写在for循环内部,每次循环都会重复创建函数,运行效率低。
- 直接往collection.json追加带逗号的JSON对象,最终生成的文件末尾会多一个逗号,不是合法的JSON格式,无法被常规JSON解析工具读取。
修改后可直接运行的代码
from collections import OrderedDict import json def get_nested_value(data, path): """按路径逐级提取嵌套字段,不存在则抛出明确异常""" temp = data for path_key in path: if path_key not in temp: raise KeyError(f"嵌套路径缺失字段:{path_key}") temp = temp[path_key] return temp def sort_dict_by_order(data, key_order): """按指定顺序排列字典顶层键,指定键排前面,其余键保留在后方不丢失""" ordered = OrderedDict() # 先写入指定顺序的键 for key in key_order: if key in data: ordered[key] = data[key] # 写入剩余未指定顺序的键 for key in data: if key not in ordered: ordered[key] = data[key] return ordered # ========== 配置项,按实际需求修改 ========== TOTAL_FILES = 10 DESIRED_KEY_ORDER = ("edition", "name", "description", "image", "attributes") # 二级键edition的实际存储路径,比如("properties", "edition")代表edition在顶层properties字段下 EDITION_NESTED_PATH = ("properties", "edition") OUTPUT_FILE = "collection.json" # ========================================== # 初始化输出文件,写入JSON数组起始标识 with open(OUTPUT_FILE, "w", encoding="utf-8") as f: f.write("[") for i in range(TOTAL_FILES): nft_id = i + 1 filename = f"{nft_id}.json" try: with open(filename, "r", encoding="utf-8") as f: raw_data = json.load(f) # 提取二级层级的edition字段到顶层 raw_data["edition"] = get_nested_value(raw_data, EDITION_NESTED_PATH) # 按指定顺序排序 sorted_data = sort_dict_by_order(raw_data, DESIRED_KEY_ORDER) # 追加写入输出文件 with open(OUTPUT_FILE, "a", encoding="utf-8") as f: f.write(json.dumps(sorted_data, indent=4, ensure_ascii=False) + ",\n") print(f"NFT #{nft_id} 处理完成") except Exception as e: print(f"NFT #{nft_id} 缺失或格式错误,跳过:{str(e)}") # 修正JSON格式,移除末尾多余逗号,补全数组闭合标识 with open(OUTPUT_FILE, "rb+") as f: f.seek(-2, 2) f.truncate() f.write(b"\n]")
使用说明
- 只需要修改
EDITION_NESTED_PATH配置为你实际JSON中edition所在的二级路径即可,比如你的edition存在于顶层meta字段下,就把这个值改成("meta", "edition"),代码会自动逐级查找字段,不会直接触发无意义的KeyError。 - 代码默认保留JSON中所有其他未指定排序顺序的字段,不会因为排序丢内容。
- 最终生成的
collection.json是标准合法的JSON数组格式,不需要手动修正格式,可以直接被各类JSON解析工具读取。 - 所有文件读写加了utf-8编码配置,处理中文、特殊符号时不会出现乱码。
内容的提问来源于stack exchange,提问作者P. Campbell
相关产品推荐
相关产品推荐

