如何使用Python对两个包含超3500万数值的.txt文件对应求和并写入第三个文件?
这个需求的核心痛点就是处理超大文件时的内存问题——3500万+的数值要是一次性全读进内存,普通电脑直接就崩了。最稳妥的方案是逐行同步读取、计算、写入,全程内存占用极低,下面给你详细的实现步骤和代码:
核心思路
绝对不能用read()这类一次性加载整个文件的方法,必须采用流式处理:同时打开两个输入文件和一个输出文件,同步读取每一行的数值,对应位置相加后立即写入结果文件,全程只在内存中保留当前行的数据。
实现代码(适配一行多数值的情况,和你的示例一致)
def add_corresponding_values(file1_path, file2_path, output_path, decimal_places=None): with open(file1_path, 'r') as f1, open(file2_path, 'r') as f2, open(output_path, 'w') as f_out: # 同步遍历两个文件的每一行,zip会自动处理到较短文件的末尾 for line_num, (line1, line2) in enumerate(zip(f1, f2), start=1): # 去除每行首尾空白,分割成单个数值的字符串列表 nums1 = line1.strip().split() nums2 = line2.strip().split() # 可选:检查当前行的数值数量是否匹配,避免错位 if len(nums1) != len(nums2): raise ValueError(f"第{line_num}行数值数量不匹配:文件1有{len(nums1)}个,文件2有{len(nums2)}个") # 对应位置转成float相加 result_nums = [float(n1) + float(n2) for n1, n2 in zip(nums1, nums2)] # 格式化结果,两种模式可选 if decimal_places is not None: # 统一保留指定小数位数,比如decimal_places=5就保留5位 formatted = [f"{num:.{decimal_places}f}" for num in result_nums] else: # 模仿你的示例:自动去掉末尾无意义的0和多余的小数点 formatted = [] for num in result_nums: str_num = str(num) if '.' in str_num: str_num = str_num.rstrip('0').rstrip('.') formatted.append(str_num) # 把格式化后的数值用空格拼接,写入结果文件 f_out.write(' '.join(formatted) + '\n') # 调用示例,替换成你的实际文件路径 if __name__ == "__main__": add_corresponding_values( file1_path="file1.txt", file2_path="file2.txt", output_path="result.txt", # 如果需要统一保留5位小数,就打开下面这行注释 # decimal_places=5 )
关键细节说明
- 内存效率拉满:
zip(f1, f2)会逐行读取两个文件,每次只在内存中存当前行的数值列表,内存占用可以忽略不计,完美适配3500万+的大数据量。 - 容错机制:代码里加了行号和数值数量检查,如果两个文件对应行的数值个数不一样,会抛出明确的错误提示,方便你排查数据问题。
- 格式化灵活:
- 要是你需要统一精度,比如所有结果都保留5位小数,直接设置
decimal_places=5就行; - 想和示例一样自动去掉末尾的0,就不用传这个参数,代码会自动处理。
- 要是你需要统一精度,比如所有结果都保留5位小数,直接设置
- 性能优化:用了列表推导式和内置字符串方法,比手动循环拼接快很多,处理超大文件的速度完全够用。
适配单个数值占一行的情况
如果你的文件是每个数值单独占一行(不是示例里的一行多个),只需要修改核心循环部分,去掉split()即可:
def add_single_line_values(file1_path, file2_path, output_path, decimal_places=None): with open(file1_path, 'r') as f1, open(file2_path, 'r') as f2, open(output_path, 'w') as f_out: for line_num, (line1, line2) in enumerate(zip(f1, f2), start=1): try: num1 = float(line1.strip()) num2 = float(line2.strip()) except ValueError: raise ValueError(f"第{line_num}行存在非数值内容") result = num1 + num2 # 格式化逻辑同上 if decimal_places is not None: formatted_str = f"{result:.{decimal_places}f}" else: formatted_str = str(result).rstrip('0').rstrip('.') if '.' in str(result) else str(result) f_out.write(formatted_str + '\n')
内容的提问来源于stack exchange,提问作者Nicolas Guibal
相关产品推荐
相关产品推荐

