2009-07-09 6 views
9

呼び出すとStopIteration例外とリスト内包表記:ファイルが20の以上の行を持っている場合Pythonの:私はcsvファイルから最大20行を読みたい

rows = [csvreader.next() for i in range(20)] 

は、罰金の作品はそうでない場合を呼び出すとStopIteration例外で失敗します。

イテレータを扱うエレガントな方法は、リストの理解にStopIteration例外をスローする可能性がありますか、または定期的なforループを使用する必要がありますか?

答えて

11

itertools.isliceを使用できます。リストスライシングのイテレータバージョンです。イテレータの要素が20未満の場合は、すべての要素が返されます。

import itertools 
rows = list(itertools.islice(csvreader, 20)) 
+0

ありがとうございます。 StopIterationを処理するためにリストの内容を更新する必要があるようですね。 "for"はそれに対処するために既に更新されているようです(暗黙のうちに例外が発生したときに反復をやめてしまいます)、リストの理解の理由が分かりません。 – Parand

+2

は、iterableを基準にしたStopIterationを捕捉し、そのスイート内の他のオブジェクトは捕捉しません。例えば、範囲(10)内のiについて C = ITER(範囲(5)) :私は \tプリント、c.next() は、cに対して呼び出すとStopIteration例外が発生します。 – Mapio

+3

forループは、暗黙的にStopIterationを捕捉しません。イテレータの次のメソッドによってスローされた場合にのみ、ループボディにスローされます。あなたの質問では、csvreader.next()はループ本体に似ています。 – Miles

-1

行番号を追跡するためにも必要何らかの理由ならば、私はあなたをお勧めします:

rows = zip(xrange(20), csvreader) 

ない場合は、十分後にそれを取り除くか、...することができ、

+0

行番号が必要な場合は、確実にlen()に依存しないという利点を持つenumerate().. –

0

itertools.izip2)は、リストの理解を容易にする方法を提供しますが、isliceはこの場合の方法と思われます。

from itertools import izip 
[row for (row,i) in izip(csvreader, range(20))] 
+0

を使用してください(例えば、apsw.cursorの場合) – Mark

+0

'enumerate'が正しい方法です範囲を圧縮することはありません。 – ArekBulski

関連する問題