Python循环追加JSON列表至文件时如何添加逗号分隔?
解决实时追加JSON列表的格式问题
你的问题很典型——因为要实时保存数据避免令牌过期,不能一次性攒完所有数据再写入,导致每次追加的小列表拼在一起成了无效的JSON。下面给你几个实用的解决方案:
方案1:构建单个合法的JSON数组(推荐)
这个方法会让最终文件是一个标准的JSON数组,格式完全正确。核心思路是先写数组开头,然后逐个追加元素(处理好逗号),最后补数组结尾:
import json from collections import defaultdict import os # 初始化文件:如果文件不存在/为空,先写入数组开头的'[' file_path = 'data.json' is_first_item = not os.path.exists(file_path) or os.path.getsize(file_path) == 0 with open(file_path, mode='a') as f: if is_first_item: f.write('[') for item in music: data = defaultdict(list) genre = item[0] artist = item[1] track = item[2] # 这里放你的API调用和数据处理逻辑 data['genre'] = genre data['artist'] = artist data['track'] = track # 处理JSON字符串和逗号 json_str = json.dumps(data, indent=4) with open(file_path, mode='a') as f: if not is_first_item: # 非第一个元素,先写逗号换行保证格式美观 f.write(',\n') f.write(json_str) is_first_item = False # 最后写入数组结尾的']' with open(file_path, mode='a') as f: f.write('\n]')
注意点:
- 如果程序中途崩溃(比如令牌过期中断),文件会缺少最后的
],下次运行时可以先检查文件末尾:如果不是],可以先补个逗号再继续写入新元素,最后再补]。 - 用
os.path.getsize(file_path) == 0处理空文件的情况,避免刚创建的空文件直接写元素导致格式错误。
方案2:使用JSON Lines格式(更简单,适合实时场景)
如果后续处理数据时可以接受逐行解析,JSON Lines(每行一个独立JSON对象)是更省心的选择——不需要处理逗号,每次直接追加一行JSON字符串即可:
import json from collections import defaultdict for item in music: data = defaultdict(list) genre = item[0] artist = item[1] track = item[2] # API调用和数据处理 data['genre'] = genre data['artist'] = artist data['track'] = track # 直接追加一行JSON对象 with open('data.jsonl', mode='a') as f: json.dump(data, f) f.write('\n')
优势:
- 完全不用担心逗号问题,每行都是独立的有效JSON
- 中途崩溃也不会影响已写入的数据,后续可以逐行读取解析:
with open('data.jsonl', mode='r') as f: for line in f: item = json.loads(line.strip()) # 处理单个item
方案3:修改已有文件的结尾(不推荐大文件)
如果必须用标准JSON数组且不想重新初始化文件,可以每次追加前修改文件末尾的],再加入新元素:
import json from collections import defaultdict import os file_path = 'data.json' for item in music: data = defaultdict(list) genre = item[0] artist = item[1] track = item[2] # API调用和数据处理 data['genre'] = genre data['artist'] = artist data['track'] = track json_str = json.dumps(data, indent=4) if os.path.exists(file_path) and os.path.getsize(file_path) > 0: # 读取文件内容,去掉最后的']' with open(file_path, mode='r+') as f: f.seek(-2, os.SEEK_END) # 假设最后是'\n]',回退2个字符 f.truncate() # 写入逗号、新元素和']' f.write(',\n') f.write(json_str) f.write('\n]') else: # 第一次写入,直接写数组 with open(file_path, mode='w') as f: json.dump([data], f, indent=4)
缺点:
- 每次都要修改文件末尾,大文件时效率低,而且如果文件末尾格式不符合预期(比如有多余空格),
seek的位置会出错,容易导致文件损坏。
推荐优先选方案1或方案2,根据你后续处理数据的需求来决定——如果需要标准JSON数组就用方案1,追求简单可靠就用方案2。
内容的提问来源于stack exchange,提问作者8-Bit Borges




