3

我正在尝试将 0 到 1000000000 的数字列表作为字符串直接写入文本文件。我还希望每个数字都有前导零,最多十位数,例如,0000000000, 0000000001, 0000000002, 0000000003, ... n.但是我发现这对我的口味来说太长了。

我可以使用seq,但不支持前导零,我宁愿避免使用awk和其他辅助工具来处理这些任务。我知道仅用 C 编写代码就能带来显着的加速收益,但我不想诉诸于此。我正在考虑将一些函数映射到一个大列表并循环执行它们,但是我只有 2GB 的可用 RAM,所以在处理我的问题时请记住这一点。

我正在使用Python-Progressbar,并且我得到了大约 2 小时的 ETA。如果有人能给我一些关于如何解决这个问题的建议,我将不胜感激:

pbar = ProgressBar(widgets=[Percentage(), Bar(), ' ', ETA(), ' ', FileTransferSpeed()], maxval=1000000000).start()

with open('numlistbegin','w') as numlist:
    limit, nw, pu = 1000000000, numlist.write, pbar.update

    for x in range(limit):
        nw('%010d\n'%(x,))
        pu(x)
pbar.finish()

编辑:所以我发现格式化(无论您使用什么编程语言)会产生大量开销。Seq可以快速完成工作,但使用格式化选项 (-f) 会慢得多。但是,如果有人仍然想提供 python 解决方案,那将是最受欢迎的。

4

2 回答 2

3

FWIWseq确实有一个格式化选项:

$ seq -f "%010g" 1 5
0000000001
0000000002
0000000003
0000000004
0000000005

您的长时间可能与记忆有关。对于大范围,使用 xrange 更节省内存,因为它不会在开始之前尝试计算整个范围并将其存储在内存中。请参阅标题为“您是否应该始终偏爱 xrange() 而不是 range()?

编辑:使用 Python 3 意味着 xrange 与 range 的使用无关。

于 2013-07-22T16:04:02.493 回答
2

我做了一些实验,发现大批量编写可以提高大约 30% 的性能。我不确定为什么您的代码需要 2 个小时才能生成文件——除非进度条正在扼杀性能。如果是这样,您应该应用相同的批处理逻辑来更新进度条。我的旧 Windows 机器将在大约 73 秒内创建所需大小的十分之一的文件。

# Python 2.
# Change xrange to range for Python 3.

import time

start_time = time.time()

limit = 100000000  # 1/10 your limit.
skip  = 1000       # Batch size.

with open('numlistbegin', 'w') as fh:
    for i in xrange(0, limit, skip):
        batch = ''.join('%010d\n' % j for j in xrange(i, i + skip, 1))
        fh.write(batch)

print time.time() - start_time   # 73 sec. (106 sec. without batching).
于 2013-07-22T16:07:30.550 回答