私はおそらくただ使うでしょうitertools.islice
。ファイル ハンドルのような iterable に対して islice を使用すると、ファイル全体がメモリに読み込まれることはなく、最初の 4002 行ができるだけ早く破棄されます。必要な 2 行をかなり安価にリストにキャストすることもできます (行自体がそれほど長くないと仮定します)。次に、with
ブロックを終了して、ファイルハンドルを閉じることができます。
from itertools import islice
with open('afile') as f:
lines = list(islice(f, 4003, 4005))
do_something_with(lines)
アップデート
しかし、神聖な牛は、複数のアクセスに対してラインキャッシュが高速です。islice と linecache を比較するために 100 万行のファイルを作成しましたが、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
ファイルを常に再インポートして再読み込みする:
これは実用的なテストではありませんが、各ステップでラインキャッシュを再インポートしても islice よりわずか 1 秒遅いだけです。
>>> timeit("from linecache import getline; getline('afile', 4003) + getline('afile', 4004)", number=10**5)
15.613967180252075
結論
はい、linecache は、常に linecache を再作成する以外はすべて islice よりも高速ですが、誰がそれを行うのでしょうか? 可能性のあるシナリオ (数行のみを 1 回読み取り、多数の行を 1 回読み取り) では、linecache の方が高速で簡潔な構文を示しますが、islice
構文も非常にクリーンで高速であり、ファイル全体をメモリに読み取ることはありません。 . RAM が不足している環境では、このislice
ソリューションが正しい選択になる場合があります。非常に高速な要件の場合は、ラインキャッシュの方が適している場合があります。ただし、実際には、ほとんどの環境では、どちらの時間も十分に小さいため、ほとんど問題にはなりません。