如何将制表符分隔文件转为指定格式JSON并保留数值类型
制表符文件转指定嵌套JSON的数值格式修正方案
核心问题分析
要解决的痛点包括:
- 读取文件时数值带换行符、被识别为字符串
- 转数值类型时整数自动变为浮点数(如
5变成5.0) - 小数被JSON序列化为科学计数法(如
0.0001变成1e-04)
修正后的代码实现
import json import csv import decimal class CustomJSONEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, decimal.Decimal): # 整数型Decimal转成JSON整数 if obj == obj.to_integral(): return int(obj) # 非整数型Decimal转成普通小数字符串,避免科学计数法 else: return format(obj, 'f') return super().default(obj) def tsv_to_json(tsv_file_path, sample_id): result = { "sample_id": sample_id, "data": [] } # 用csv模块处理制表符分隔文件,兼容性更强 with open(tsv_file_path, 'r', encoding='utf-8') as f: reader = csv.reader(f, delimiter='\t') for row in reader: if len(row) != 2: continue # 跳过格式错误的行 key = row[0].strip() value_str = row[1].strip() # 用Decimal解析数值,完全保留原始格式 try: value = decimal.Decimal(value_str) except decimal.InvalidOperation: # 非数值类型直接保留字符串(可根据需求调整) value = value_str result["data"].append({"key": key, "value": value}) # 用自定义编码器生成符合要求的JSON return json.dumps(result, cls=CustomJSONEncoder, ensure_ascii=False, indent=4) # 调用示例 if __name__ == "__main__": input_tsv = "WGNP1000001.list.txt" target_sample_id = "WGNP1000001" json_result = tsv_to_json(input_tsv, target_sample_id) # 打印输出或写入文件 print(json_result) with open(f"{target_sample_id}.json", 'w', encoding='utf-8') as out_f: out_f.write(json_result)
关键修复点说明
文件读取处理:
- 用
csv.reader指定制表符分隔,比手动split('\t')更稳定,能处理行内包含特殊字符的情况 - 用
strip()去除数值前后的换行符、空白字符,解决数值带换行的问题
- 用
数值类型保留:
- 用
decimal.Decimal解析数值,完全保留原始字符串的数值格式,避免浮点数精度丢失或自动转科学计数法 - 自定义JSON编码器判断Decimal类型:整数型转JSON整数,非整数型转普通小数字符串,确保输出格式与原始文件一致
- 用
异常处理:
- 对非数值类型的内容直接保留字符串,避免解析报错,增强代码鲁棒性
内容的提问来源于stack exchange,提问作者user3214212
相关产品推荐
相关产品推荐

