web-dev-qa-db-ja.com

Pythonを使用してファイルを反復処理する

ファイルの繰り返しを理解するのに問題があります。ここで、インタープリターに入力する内容と結果に進みます。

>>> f = open('baby1990.html', 'rU')
>>> for line in f.readlines():
>>>  print(line)

>>> ...
>>> ... all the lines from the file appear here
>>> ...

同じ開いているファイルをもう一度繰り返してみると、何も得られません!!!!

>>> f = open('baby1990.html', 'rU')
>>> for line in f.readlines():
>>>    print(line)
>>>
>>>

出力はまったくありません。これを解決するには、ファイルをclose()してから、読み取りのために再度開きます!!それは正常な動作ですか?

49
MYZ

はい、それは正常な動作です。基本的に最初にファイルの最後まで読みます(テープを読み取るように画像を並べ替えることができます)。したがって、f.seek(0)を使用して、リセットしない限り、ファイルからそれ以上読み取ることはできません。ファイルの先頭に再配置するか、ファイルを閉じてから再度開くと、ファイルの先頭から開始されます。

必要に応じて、代わりに自動的にファイルを閉じるwith構文を使用できます。

例えば。、

with open('baby1990.html', 'rU') as f:
  for line in f:
     print line

このブロックの実行が終了すると、ファイルは自動的に閉じられるため、明示的にファイルを閉じずにこのブロックを繰り返し実行し、この方法でファイルを再度読み取ることができます。

77
Levon

ファイルオブジェクトはファイルを読み取るときに、ポインターを使用してその場所を追跡します。ファイルの一部を読んだ後、後でそのファイルに戻ると、中断したところから再開します。ファイル全体を読み取って同じファイルオブジェクトに戻ると、空のファイルを読み取るようなものになります。これは、ポインターがファイルの最後にあり、読み取るものが何もないためです。 file.tell()を使用して、ファイル内のポインターの場所を確認し、_file.seek_を使用してポインターを設定できます。例えば:

_>>> file = open('myfile.txt')
>>> file.tell()
0
>>> file.readline()
'one\n'
>>> file.tell()
4L
>>> file.readline()
'2\n'
>>> file.tell()
6L
>>> file.seek(4)
>>> file.readline()
'2\n'
_

また、file.readlines()はファイル全体を読み取り、リストとして保存することを知っておく必要があります。以下を置き換えることができるので、知っておくと便利です。

_for line in file.readlines():
    #do stuff
file.seek(0)
for line in file.readlines():
    #do more stuff
_

で:

_lines = file.readlines()
for each_line in lines:
    #do stuff
for each_line in lines:
    #do more stuff
_

また、次の操作を行うことで、ファイル全体をメモリに保持せずに、一度に1行ずつファイルを反復処理することもできます(これは非常に大きなファイルに非常に役立ちます)。

_for line in file:
    #do stuff
_
15
Bi Rico

ファイルオブジェクトはbufferです。バッファーから読み取ると、読み取った部分が消費されます(読み取り位置が前方にシフトされます)。ファイル全体を読み通す場合、読み取り位置はEOFにあるため、読み取るものが残っていないため、何も返されません。

何らかの理由で、ファイルオブジェクトの読み取り位置をリセットする必要がある場合は、次の操作を実行できます。

f.seek(0)
8
Joel Cornett

もちろん。それは正常で健全な行動です。閉じて再度開く代わりに、ファイルをrewindできます。

1
ch3ka