Python将含嵌套数组的JSON转为CSV文件后仅输出一行的问题求解
问题根因
- 缩进错误:文件写入代码被错误放在了遍历JSON条目的
for循环内部,每次循环都会以覆盖写模式重新创建文件,之前的写入内容全部被清空,最终仅保留最后一次循环写入的1行数据。 - 列表处理逻辑bug:
get_leaves函数处理数组时,使用update合并每个元素的解析结果,相同键名的内容会被后续元素覆盖,导致多元素数组仅保留最后一个元素的内容。
修复后代码
import json import csv from azure.storage.blob import BlobServiceClient blob_service_client = BlobServiceClient.from_connection_string(constr) container_client = blob_service_client.get_container_client(container_name) blob_client = container_client.get_blob_client(filename) streamdownloader = blob_client.download_blob() JsonObject = json.loads(streamdownloader.readall()) def get_leaves(item, key=None): if isinstance(item, dict): leaves = {} for k in item.keys(): leaves.update(get_leaves(item[k], k)) return leaves elif isinstance(item, list): # 多元素数组如果需要单独拆行可以调整此处逻辑,当前逻辑将数组转JSON字符串存储避免覆盖 return {key: json.dumps(item, ensure_ascii=False)} else: return {key : item} fieldnames = set() # 先遍历所有条目收集完整字段名 for entry in JsonObject: fieldnames.update(get_leaves(entry).keys()) # 收集完所有字段后仅打开一次文件写入全部数据 with open('C:/Users/Desktop/output.csv', 'w', newline='', encoding='utf-8-sig') as f_output: csv_output = csv.DictWriter(f_output, fieldnames=sorted(fieldnames)) csv_output.writeheader() csv_output.writerows(get_leaves(entry) for entry in JsonObject)
大体积JSON优化建议
- 流式读取避免内存溢出:替换全量加载JSON的逻辑,使用
ijson库从Blob流中逐条目读取JSON数据,无需将整个GB级JSON文件一次性加载到内存中,避免OOM崩溃。 - 嵌套数组按需展开:如果业务需要把嵌套数组的每个元素作为单独的CSV行存储,可以修改
get_leaves的返回逻辑,返回生成器遍历所有数组元素生成多条记录,而不是把数组序列化为字符串。 - 增量写入:如果JSON条目数极多,可以分批次写入CSV,不需要等所有字段收集完成后再写入,提前预设好字段列表即可进一步提升处理效率。
内容的提问来源于stack exchange,提问作者Ahmed Shaalan
相关产品推荐
相关产品推荐

