RobM..
38
我认为探索使用genexp的好处会很有趣,所以这是我的看法.
问题中的示例使用方括号来创建临时列表,因此等效于:
file.writelines( list( "%s\n" % item for item in list ) )
哪个不必要地构造了将要写出的所有行的临时列表,这可能会消耗大量内存,具体取决于列表的大小以及输出的详细str(item)程度.
删除方括号(相当于删除list()上面的包装调用)将改为将临时生成器传递给file.writelines():
file.writelines( "%s\n" % item for item in list )
此生成器将item按需创建对象的换行符表示(即,当它们被写出时).这很好,原因有两个:
即使对于非常大的列表,内存开销也很小
如果str(item)速度很慢,则在处理每个项目时文件中都会显示进度
这可以避免内存问题,例如:
In [1]: import os
In [2]: f = file(os.devnull, "w")
In [3]: %timeit f.writelines( "%s\n" % item for item in xrange(2**20) )
1 loops, best of 3: 385 ms per loop
In [4]: %timeit f.writelines( ["%s\n" % item for item in xrange(2**20)] )
ERROR: Internal Python error in the inspect module.
Below is the traceback from this internal error.
Traceback (most recent call last):
...
MemoryError
(我通过将Python的最大虚拟内存限制为~100MB来触发此错误ulimit -v 102400).
将内存使用放在一边,这种方法实际上并不比原来快:
In [4]: %timeit f.writelines( "%s\n" % item for item in xrange(2**20) )
1 loops, best of 3: 370 ms per loop
In [5]: %timeit f.writelines( ["%s\n" % item for item in xrange(2**20)] )
1 loops, best of 3: 360 ms per loop
(Linux上的Python 2.6.2)