如何在Python3中按列批量写入多行至制表符分隔文件
按列写入多行到TSV文件的Python实现
这个需求我之前也碰到过,直接按列写确实不太好操作——毕竟文件本质是流式顺序存储的,没法直接跳到指定行去追加列内容。不过有两种靠谱的解决思路,你可以根据数据体量来选:
方法一:先转置数据再写入(适合中小体量数据)
如果你的数据不会大到撑爆内存,最直接的方式就是先把按列组织的数据转置成按行组织,然后再写入TSV文件。Python里用zip(*columns)就能轻松完成转置。
示例代码
# 按列组织的数据:每个子列表对应一列的所有行内容 column_data = [ ["row1_col1", "row2_col1", "row3_col1"], # 第1列的3行值 ["row1_col2", "row2_col2", "row3_col2"], # 第2列的3行值 ["row1_col3", "row2_col3", "row3_col3"], # 第3列的3行值 ["row1_col4", "row2_col4", "row3_col4"], # 第4列的3行值 ["row1_col5", "row2_col5", "row3_col5"], # 第5列的3行值 ] # 转置列数据为行数据:zip(*column_data)会把每列的对应元素拼成一行 rows = list(zip(*column_data)) # 写入制表符分隔文件 with open("output.tsv", "w", encoding="utf-8") as f: for row in rows: # 用制表符连接每行的字段,末尾加换行符 f.write("\t".join(row) + "\n")
运行后生成的output.tsv内容就是标准的TSV格式:
row1_col1 row1_col2 row1_col3 row1_col4 row1_col5 row2_col1 row2_col2 row2_col3 row2_col4 row2_col5 row3_col1 row3_col2 row3_col3 row3_col4 row3_col5
方法二:临时文件分阶段处理(适合超大型文件)
如果你的文件特别大,一次性把所有数据加载到内存会导致内存溢出,那就可以用临时文件+逐行合并的方式:
- 先把每一列的内容单独写入一个临时文件;
- 同时打开所有临时文件,每次从每个文件读取一行,拼接成完整的一行写入最终文件;
- 最后清理临时文件。
示例代码
import tempfile import os # 模拟生成大型列数据的生成器(避免一次性加载所有数据) def generate_column(col_index): # 这里模拟生成3行的列内容,实际可以替换成你的数据源(比如从数据库/其他文件读取) for row_num in range(3): yield f"row{row_num+1}_col{col_index+1}" temp_file_paths = [] try: # 步骤1:为每一列创建临时文件并写入内容 for col_idx in range(5): # 创建临时文件(delete=False表示程序结束后不自动删除,方便后续合并) with tempfile.NamedTemporaryFile(mode="w+", delete=False, encoding="utf-8") as temp_f: for value in generate_column(col_idx): temp_f.write(f"{value}\n") temp_file_paths.append(temp_f.name) # 步骤2:合并所有临时文件到最终TSV with open("large_output.tsv", "w", encoding="utf-8") as final_f: # 同时打开所有临时文件 with open(temp_file_paths[0], "r", encoding="utf-8") as f0, \ open(temp_file_paths[1], "r", encoding="utf-8") as f1, \ open(temp_file_paths[2], "r", encoding="utf-8") as f2, \ open(temp_file_paths[3], "r", encoding="utf-8") as f3, \ open(temp_file_paths[4], "r", encoding="utf-8") as f4: # 逐行读取每个临时文件,拼接成完整行写入 while True: # 读取每列的当前行(strip去掉换行符) line0 = f0.readline().strip() line1 = f1.readline().strip() line2 = f2.readline().strip() line3 = f3.readline().strip() line4 = f4.readline().strip() # 如果所有行都为空,说明已经读完所有内容 if not any([line0, line1, line2, line3, line4]): break # 用制表符拼接并写入最终文件 final_f.write(f"{line0}\t{line1}\t{line2}\t{line3}\t{line4}\n") finally: # 步骤3:清理临时文件 for path in temp_file_paths: if os.path.exists(path): os.unlink(path)
这种方法的优势是内存占用极低,不管你的文件有多大,每次只处理一行数据,适合处理GB级别的大型TSV文件。
内容的提问来源于stack exchange,提问作者jing
相关产品推荐
相关产品推荐

