You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:57:11