2

次のようなコードがあります。

#opened file f
goto_line = num_lines #Total number of lines
while not found:
   line_str = next(itertools.islice(f, goto_line - 1, goto_line))
   goto_line = goto_line/2
   #checks for data, sets found to True if needed

line_str は最初のパスでは正しいですが、その後のすべてのパスは別の行を読み取る必要があります。

たとえば、goto_line は 1000 から始まります。1000 行目までは問題なく読み取れます。次に、次のループ goto_line は 500 ですが、500 行目は読み取れません。1000 に近い行が読み取られます。

必要以上に読み取らずに、大きなファイルの特定の行を読み取ろうとしています。ある行に後方にジャンプすることもあれば、前方にジャンプすることもあります。

私は linecache を試しましたが、通常、このコードを同じファイルに対して複数回実行することはありません。

4

2 に答える 2

5

Python イテレーターは 1 回だけ使用できます。これは、例によって最も簡単に確認できます。次のコード

from itertools import islice
a = range(10)
i = iter(a)
print list(islice(i, 1, 3))
print list(islice(i, 1, 3))
print list(islice(i, 1, 3))
print list(islice(i, 1, 3))

版画

[1, 2]
[4, 5]
[7, 8]
[]

スライスは、前回停止したところから常に開始されます。

コードを機能させる最も簡単な方法は、 を使用f.readlines()してファイル内の行のリストを取得し、次に通常の Python リスト スライスを使用すること[i:j]です。どうしても使いたい場合はislice()、 を使って毎回最初から読み始めることもできますがf.seek(0)、これは非常に非効率的です。

于 2011-02-16T18:32:54.930 に答える
0

ファイルに戻ることはできません (この方法 - ファイルを開く方法によっては、おそらく何らかの方法があります)。標準のファイル反復子 (実際、ほとんどの反復子 - Python の反復子プロトコルは前方反復子のみをサポートします) は前方にのみ移動します。したがって、行を読み取った後k、別のk/2行を読み取ると、実際にはk+k/2th 行が表示されます。

ファイル全体をメモリに読み込むこともできますが、大量のデータがあるため、メモリの消費が問題になる可能性があります。file.seekファイルをスクロールするために使用できます。しかし、それでもまだ多くの作業が必要です。おそらく、メモリ マップト ファイルを使用できますか? ただし、行が固定サイズの場合にのみ可能です。必要に応じて、チェックしたい行番号を事前に計算し、それらすべての行int(log_2(line_count)) + 1を 1 回の反復で保存することができます (私が間違っていなければ、大まかに多すぎるべきではありません)。スクロールする必要はありません。ファイル全体を読み取った後に戻ります。

于 2011-02-16T18:33:50.727 に答える