我可能只会使用itertools.islice
. 在像文件句柄这样的可迭代对象上使用 islice 意味着永远不会将整个文件读入内存,并且会尽快丢弃前 4002 行。你甚至可以很便宜地将你需要的两行放入一个列表中(假设这些行本身不是很长)。然后你可以退出with
块,关闭文件句柄。
from itertools import islice
with open('afile') as f:
lines = list(islice(f, 4003, 4005))
do_something_with(lines)
更新
但是对于多次访问来说,圣牛的 linecache 速度更快。我创建了一个百万行的文件来比较 islice 和 linecache,而 linecache 把它吹走了。
>>> timeit("x=islice(open('afile'), 4003, 4005); print next(x) + next(x)", 'from itertools import islice', number=1)
4003
4004
0.00028586387634277344
>>> timeit("print getline('afile', 4003) + getline('afile', 4004)", 'from linecache import getline', number=1)
4002
4003
2.193450927734375e-05
>>> timeit("getline('afile', 4003) + getline('afile', 4004)", 'from linecache import getline', number=10**5)
0.14125394821166992
>>> timeit("''.join(islice(open('afile'), 4003, 4005))", 'from itertools import islice', number=10**5)
14.732316970825195
不断地重新导入和重新读取文件:
这不是一个实际测试,但即使在每一步重新导入 linecache 也只比 islice 慢一秒。
>>> timeit("from linecache import getline; getline('afile', 4003) + getline('afile', 4004)", number=10**5)
15.613967180252075
结论
是的,除了不断地重新创建 linecache 之外,linecache 比 islice 快,但是谁这样做呢?对于可能的情况(一次只读取几行,一次读取多行),linecache 更快并且呈现简洁的语法,但islice
语法也非常干净和快速,并且不会将整个文件读入内存. 在 RAM 紧张的环境中,该islice
解决方案可能是正确的选择。对于非常高的速度要求,linecache 可能是更好的选择。但实际上,在大多数环境中,这两个时间都足够小,几乎无关紧要。