2016-09-02 14 views
2

目的:カウントが実際の行数より大きい場合、exceptブロック:ユーザに通知してEnterを押します。 countをファイル内の行の総数と等しく設定し、ループを再試行してください。例外処理中に奇妙なネストされたループ動作

count = 10000 
with open('mobydick_ch1.txt') as f: 

     while 1: 
      lines = [] 
      try: 
       for i in range(count): 
        lines.append(next(f)) # iterate through file and append each line in range 
        break 
      except StopIteration: 
       if not input("File does not contain that many lines, press enter to continue printing maximum lines:"): 
        for i, k in enumerate(f, 1): 
         count = i 

     f.close() # close file 

     # format output. enumerate lines, start at 1 
     # http://stackoverflow.com/questions/4440516/in-python-is-there-an-elegant- 
     # way-to-print-a-list-in-a-custom-format-without-ex 
    print(''.join('Line {0}: {1}'.format(*k) for k in enumerate(lines, 1))) 

私は現在取得しています:私はEnterキーを押しますたびに

ファイルは、多くのライン、プレスが最大の行を印刷し続けるために入力することが含まれていません。この不要な動作の原因は何ですか?

+0

'f.close()'は完全に冗長です。あなたはすでにファイルをコンテキストマネージャとして使っています( 'with ...') –

+0

このヒントをありがとう! –

+0

そのための目的は何ですか?enumerate(f、1):count = i'とにかくループしますか? 10000未満の場合、ファイル内の実際の行数に 'count'を設定しようとしていますか? –

答えて

2

すでにファイルが使い果たされているので、ファイルからもう一度を読み取ることはできません。その結果、for i, k in enumerate(f, 1):ループがすぐに終了します。これは、あなたのwhile 1:ループのすべての将来の反復に適用されます。ファイルはまだ終了しており、next()のアクセスはすぐにStopIterationになります。

読み取った行の数は既に知っていますが、count = len(lines)と設定してください。ファイルをもう一度読み取ってを読むだけでcountと設定する必要はありません。

あなたがあなたの1000行を取得するためにitertools.islice()を使用した場合より良いだろう:あなたは待機にしようとしている場合

from itertools import islice 

count = 10000 
with open('mobydick_ch1.txt') as f: 
    lines = list(islice(f, count)) # list of up to count lines 
if len(lines) < count: 
    input("File does not contain that many lines, press enter to continue printing maximum lines:") 
    count = len(lines) # set count to actual number of lines 

をファイルには、少なくともcount行が含まれてまで、あなたが再する必要がありますファイルを毎回開き、最後に記録された場所を探します:

lines = [] 
pos = 0 
while len(lines) < count: 
    with open('mobydick_ch1.txt') as f: 
     f.seek(pos) 
     lines.extend(islice(f, count - len(lines))) 
     pos = f.tell() 
    if len(lines) < count: 
     input("File does not contain that many lines, press enter to continue printing maximum lines:") 
+0

お返事ありがとうございます。例外がなくなるまでリストが空であれば、 'lines'に行を表示することで何を意味するのかよく分かりません。私はenumerate(f、1)の 'i.kの直上に' f.seek(0) 'を配置しようとしました:'と同じ結果を得ています –

+0

@ A.Michael: 'StopIteration'は、ライン。その時点までの全ての行*が 'lines'リストに追加されます。 'lines'が空の場合は、ファイル内に*の行*が全くないことを意味します。つまり、*で始まるファイルは空です。 –

+0

@A.Michael:ああ、ファイルを再オープンしなくても無限にループしています... –

関連する問題