如何从非标准拼接JSON文件提取对象并存储至列表?
解决JSON多对象提取的问题
你的问题核心在于生成的JSON文件格式不标准——现在的文件是把多个独立的JSON对象直接拼接在一起,而非合法的JSON数组,所以json.load(f)没办法一次性解析整个文件。下面分两种情况给你解决方案:
一、从根源修正:生成标准JSON数组(推荐)
你原来的生成代码是循环写入每个对象的JSON字符串,导致文件里是多个对象连在一起,不是数组。改成先把所有对象的字典收集到列表里,再一次性写入整个列表的JSON:
import json with open('tickersjson2', 'w') as f: # 把ticks里每个对象的字典转成列表 all_data = [x.__dict__ for x in ticks] # 一次性写入标准的JSON数组(indent可选,让JSON更易读) json.dump(all_data, f, indent=2) # with语句会自动关闭文件,不需要手动f.close()
这样生成的文件内容会是标准的数组格式,比如:
[ { "name": "AIMT", "deltas": [ -0.44, 0.33 ], ... }, { "name": "GOLD", "deltas": [ -0.18, 0.52 ], ... } ]
之后读取代码就可以正常工作,修改成:
import json with open('tickersjson2-200427') as f: data = json.load(f) # 直接读取整个数组 # 遍历每个对象,提取你需要的数据 for item in data: print(f"名称: {item['name']}, 总金额: {item['voltot']}") # 可以访问其他字段,比如item['deltas'], item['cmfs']等
二、如果已经有了不标准的JSON文件,怎么读取?
如果已经生成了那种多个对象拼接的文件,我们可以逐个解析每个JSON对象:
方法1:按行读取(适合每个对象占一行的情况)
如果你的生成代码没加indent,默认json.dumps()会生成单行的JSON对象,那么可以按行读取解析:
import json result_list = [] with open('tickersjson2-200427') as f: for line in f: line = line.strip() if not line: continue # 跳过空行 try: obj = json.loads(line) result_list.append(obj) except json.JSONDecodeError as e: print(f"解析行出错: {line}, 错误: {e}") # 现在result_list就是所有对象的列表 for obj in result_list: print(obj['name'])
方法2:用JSONDecoder逐个解析(适合对象连在一起的情况)
如果对象是连在一起的(没有换行分隔),可以用json.JSONDecoder的raw_decode方法逐个提取:
import json result_list = [] with open('tickersjson2-200427', 'r') as f: content = f.read() decoder = json.JSONDecoder() pos = 0 content_len = len(content) while pos < content_len: # 跳过空白字符(空格、换行等) while pos < content_len and content[pos].isspace(): pos += 1 if pos >= content_len: break try: obj, new_pos = decoder.raw_decode(content, pos) result_list.append(obj) pos = new_pos except json.JSONDecodeError as e: print(f"解析失败,位置 {pos}: {e}") break # 遍历结果 for obj in result_list: print(f"名称: {obj['name']}, 总delta: {obj['deltatot']}")
最后提一下你原来读取代码的问题
你原来的代码for p in data['name']:是错误的:如果data是单个对象,data['name']是字符串,遍历会逐个输出字符;如果data是数组,直接访问data['name']会报错,因为数组没有name这个键。正确的做法是遍历数组里的每个对象,再访问每个对象的name字段。
内容的提问来源于stack exchange,提问作者user3311337
相关产品推荐
相关产品推荐

