You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python内存不足时如何分块将组合数据写入文本文件?

解决组合数据生成时的内存耗尽与写入速度问题

先直接上优化后的代码:

import itertools
import hashlib
import time
import re

# 预编译正则表达式,提升匹配替换效率
removechars1 = ["(", ")", "'", ",", " "]
pattern1 = re.compile('[' + ''.join(removechars1) + ']')
removechars2 = [",", " ", "-"]
pattern2 = re.compile('[' + ''.join(removechars2) + ']')

chars = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
numbers_list = range(0,25)  # 无需转成list,range本身支持迭代
chunk_size = 10000  # 每攒够10000行就写入一次,可根据内存情况调整
temp_rows = []

t0 = time.time()

with open('data.txt', 'w', encoding='utf-8') as f:
    for combination in itertools.combinations_with_replacement(chars, 10):
        # 直接拼接组合字符,避免元组转字符串带来的多余符号
        combo_str = ''.join(combination)
        for A in numbers_list:
            pure = f"{A}:{combo_str}"
            # 优化:现在pure里无多余括号引号,无需再用pattern1替换
            B = pure
            B1 = [ord(char) - 96 for char in B.lower()]
            B2 = str(B1)
            B3 = pattern2.sub('', B2)
            
            C = hashlib.sha256(B.encode('utf-8')).hexdigest()
            C1 = [ord(char) - 96 for char in C.lower()]
            C2 = str(C1)
            C3 = pattern2.sub('', C2)
            
            # 提前构造好最终写入的行格式,减少后续字符串操作
            row_str = f"{A},{B3[:10]},{C3[:10]}"
            temp_rows.append(row_str)

            # 达到块大小就批量写入
            if len(temp_rows) >= chunk_size:
                f.write('\n'.join(temp_rows) + '\n')
                temp_rows.clear()  # 清空临时列表释放内存

    # 写入剩余未达块大小的行
    if temp_rows:
        f.write('\n'.join(temp_rows) + '\n')

tdelta = time.time() - t0
print(f"总耗时:{tdelta:.2f}秒")

关键优化点说明

  • 分块写入:用temp_rows临时存储指定数量的行,攒够阈值就一次性写入文件,写完清空列表。既避免了全量数据占满内存,又减少了IO系统调用次数(比逐行写入效率高很多)。chunk_size可根据你的内存情况调整,比如改成20000或5000,找到内存占用和速度的平衡点。

  • 预编译正则:提前用re.compile编译正则表达式,避免每次re.sub时重复编译,提升字符串处理速度。

  • 优化字符串拼接:原代码中str(combination)会生成带括号、引号的字符串,后续还要额外替换。现在直接用''.join(combination)得到纯字符拼接结果,省掉了一步正则替换操作。

  • 提前格式化行内容:用f-string直接构造最终要写入的行格式,避免后续对列表转字符串再做多次replace,减少冗余操作。

  • 精简无用变量:删除原代码中未使用的B4、C4变量,减少内存占用和无效计算。

  • 用range替代list(range):numbers_list直接用range(0,25)即可,range是惰性迭代对象,无需转成list占用额外内存。

额外建议

如果组合数量极大,还可以尝试:

  • 全程依赖itertools的惰性迭代特性,不存储任何多余数据,只处理当前块内容。
  • 若CPU性能充足,可尝试多进程并行生成数据(每个进程写入单独文件,最后合并),但需注意文件写入的线程安全问题。新手建议先掌握分块写入,再考虑并行优化。

内容的提问来源于stack exchange,提问作者Juan Soto Valdez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:40:36