16

私の質問は、を使用したPythonでのファイル入力に関連していますopen()mytext.txt3行のテキストファイルがあります。私はこのファイルで2つのことをしようとしています:行を印刷することと行数を印刷することです。

次のコードを試しました。

input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
    print line
for line in input_file:
    count_lines += 1
print 'number of lines:', count_lines

結果:3行は正しく印刷されますが、「行数:0」(3行ではなく)が印刷されます。


私はそれを解決し、それを印刷するための2つの方法を見つけました3

1)2つではなく1つのループを使用します

input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
    print line
    count_lines += 1
print 'number of lines:', count_lines

2)最初のループの後、input_fileを再度定義します

input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
    print line
input_file = open('mytext.txt', 'r')
for line in input_file:
    count_lines += 1
print 'number of lines:', count_lines

私には、定義input_file = ...が1つのループに対してのみ有効であるように見えます。これは、ループに使用した後に削除されたかのようです。variable = open(filename)しかし、Pythonでどのように扱われるのか、おそらくまだ100%明確ではない理由がわかりません。

By the way, I see that in this case it is better to use only one loop. However, I feel I have to get this question clear, since there might be cases when I can/must make use of it.

4

4 に答える 4

26

ファイルハンドルは反復子です。ファイルを反復処理した後、ポインターは EOF (ファイルの終わり) に配置され、反復子はループを終了する StopIteration を発生させます。ポインターが EOF にあるファイルに反復子を使用しようとすると、StopIteration が発生して終了します。これが、2 番目のループでゼロをカウントする理由です。ファイル ポインタをinput_file.seek(0)再度開かずに巻き戻すことができます。

つまり、同じループ内で行をカウントする方が I/O 効率が高くなります。そうしないと、行をカウントするためだけに、ディスクからファイル全体をもう一度読み取る必要があります。これは非常に一般的なパターンです。

with open('filename.ext') as input_file:
    for i, line in enumerate(input_file):
        print line,
print "{0} line(s) printed".format(i+1)

Python 2.5 では、 file オブジェクトに、ステートメント インターフェイスに対処するための__enter__andが装備されています。これは、次のような構文糖衣です。__exit__with

input_file = open('filename.txt')
try:
    for i, line in enumerate(input_file):
        print line,
finally:
    input_file.close()
print "{0} line(s) printed".format(i+1)

cPython は、ガベージ コレクションが行われるとファイル ハンドルを閉じると思いますが、これがすべての実装に当てはまるかどうかはわかりません。リソース ハンドルを明示的に閉じることをお勧めします。

于 2012-07-30T17:21:31.793 に答える
5

以下を使用できなかった何らかの理由がありますか?

input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
    print line
    count_lines += 1
print 'number of lines:', count_lines

open が返すのはファイルオブジェクトです。ファイル オブジェクトは、ループするときに自身の内部位置を追跡するため、最初に試したことを実行するには、手動で先頭に巻き戻す必要があります。単独では実行されません。

于 2012-07-30T17:20:03.210 に答える
2

input_file.seek(0)2 つのループの間に を追加してみてください。これにより、ファイルが最初に巻き戻されるため、もう一度ループすることができます。

于 2012-07-30T17:20:15.623 に答える
0

モジュールファイルの入力を薄くしたいです。

ここにリンクがあります

if __name__ == "__main__":
for line in fileinput.input():
    if fileinput.isfirstline():
        print("current file: %s" % fileinput.filename())

    print("line number: %d, current file number: %d" % 
          (fileinput.lineno(), fileinput.filelineno()))
于 2013-06-10T11:38:27.747 に答える