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

基于ID关联两个CSV表并导出嵌套JSON时遇到问题

问题:CSV关联生成嵌套JSON时硬币列表为空的排查与解决

我是Python零基础新手,现有两个CSV表:一个是带ID的考古遗址(Fundorte)信息表,另一个是包含8万枚硬币(Münzen)的表,硬币通过ID与遗址关联。我希望生成嵌套结构的JSON,将每个遗址对应的所有硬币嵌套在遗址条目下,后续用于生成嵌套GeoJSON并在Leaflet中使用。

使用的代码如下:

Fundorte = open(r"C:\Users\LordK\Desktop\Daten Krmnicek\Versuch JSON STruktur\FundorteID.csv", 'r')
jsonfile = open(r"C:\Users\LordK\Desktop\Daten Krmnicek\Versuch JSON STruktur\Skript\out.json", 'w')
Münzen = open(r"C:\Users\LordK\Desktop\Daten Krmnicek\Versuch JSON STruktur\MünzenID.csv", 'r')


FuFelder = ["ID","FOverwendbar","x_KBS_25832","y_KBS_25832","PLZ"]
MüFelder = ["ID_Münze","Nr","Nominal","Prägeherr","RIC (vollständige Ansprache) (aktuell)", "Rs-Typ", "Quelle", "Zitat", "Detail 1", "Detail 2", "SF_EF_Börse", "FOverwendbar", "PLZ", "Kontext", "ID"]

FundorteReader = csv.DictReader( Fundorte, fieldnames=FuFelder)
MünzenReader = csv.DictReader( Münzen, fieldnames=MüFelder)

output=[]
for Fundrow in FundorteReader:
    Fundrow['Muenzen'] = []
    output.append(Fundrow)
    Münzen.seek(0)
    for itemrow in MünzenReader:
        if(itemrow["ID"]==Fundrow["ID"]):
            Fundrow['Muenzen'].append(itemrow)

json.dump(output, jsonfile,sort_keys=True)
jsonfile.close()
print("done")

目前遗址信息(FuFelder)能正常显示,但嵌套的硬币列表Fundrow["Muenzen"]始终为空,请问我哪里出错了?


问题原因与修复方案

1. 核心问题:迭代器耗尽导致重复读取失败

MünzenReader是一次性迭代器,第一次遍历后就会处于耗尽状态。即使调用Münzen.seek(0)重置文件指针,迭代器本身不会重新读取内容,后续循环无法获取硬币数据。

2. 次要问题:ID类型不匹配

如果两个CSV中的ID字段类型不一致(比如遗址ID是数字,硬币ID是字符串),==比较会返回False,导致匹配失败。

3. 优化建议:处理8万条数据的效率问题

原代码每遍历一个遗址就全量扫描8万条硬币数据,时间复杂度极高。建议先将硬币按ID分组存入字典,再批量匹配遗址,大幅提升效率。


修复后的代码

import csv
import json

# 读取遗址数据
with open(r"C:\Users\LordK\Desktop\Daten Krmnicek\Versuch JSON STruktur\FundorteID.csv", 'r', encoding='utf-8') as fundorte_file:
    FuFelder = ["ID","FOverwendbar","x_KBS_25832","y_KBS_25832","PLZ"]
    fundorte_reader = csv.DictReader(fundorte_file, fieldnames=FuFelder)
    fundorte_list = list(fundorte_reader)

# 预分组硬币数据:按ID存入字典
muenzen_by_id = {}
with open(r"C:\Users\LordK\Desktop\Daten Krmnicek\Versuch JSON STruktur\MünzenID.csv", 'r', encoding='utf-8') as muenzen_file:
    MüFelder = ["ID_Münze","Nr","Nominal","Prägeherr","RIC (vollständige Ansprache) (aktuell)", "Rs-Typ", "Quelle", "Zitat", "Detail 1", "Detail 2", "SF_EF_Börse", "FOverwendbar", "PLZ", "Kontext", "ID"]
    muenzen_reader = csv.DictReader(muenzen_file, fieldnames=MüFelder)
    for row in muenzen_reader:
        # 统一ID为字符串,避免类型不匹配
        id_key = str(row["ID"])
        if id_key not in muenzen_by_id:
            muenzen_by_id[id_key] = []
        muenzen_by_id[id_key].append(row)

# 匹配遗址与对应硬币
output = []
for fundrow in fundorte_list:
    fundrow_id = str(fundrow["ID"])
    # 从字典中取对应硬币,无匹配则为空列表
    fundrow['Muenzen'] = muenzen_by_id.get(fundrow_id, [])
    output.append(fundrow)

# 写入JSON文件
with open(r"C:\Users\LordK\Desktop\Daten Krmnicek\Versuch JSON STruktur\Skript\out.json", 'w', encoding='utf-8') as json_file:
    json.dump(output, json_file, ensure_ascii=False, indent=2)

print("done")

额外优化点

  • 使用with语句自动管理文件关闭,避免资源泄漏
  • 加入encoding='utf-8'确保德语特殊字符正确处理
  • ensure_ascii=False和indent=2让JSON文件更易读
  • 预分组将时间复杂度从O(N*M)降为O(N+M),处理8万条数据效率提升显著

内容的提问来源于stack exchange,提问作者Simon Holzner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 10:17:54