基于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
相关产品推荐
相关产品推荐

