私はWordごとにファイルを読み取るジェネレーターを作成しましたが、それはうまく機能します。
def Word_reader(file):
for line in open(file):
for p in line.split():
yield p
reader = Word_reader('txtfile')
next(reader)
リスト内の次のn個の値を取得する最も簡単な方法は何ですか?
使用する itertools.islice
:
list(itertools.islice(it, n))
[〜#〜]編集[〜#〜]:_itertools.islice
_を使用します。私が最初に提案した以下のパターンは悪い考えです。it
の値がn
未満になるとクラッシュします。この動作は微妙な問題に依存するため、このようなコードを読んでいる人は、その正確さを理解できない可能性があります。セマンティクス。
もあります
_[next(it) for _ in range(n)]
_itertoolsに精通していない人にとってはどちらがより明確かもしれません(?)。しかし、イテレータを頻繁に扱う場合、itertoolsはツールセットに追加する価値があります。
next(it)
が使い果たされてStopIteration
が発生した場合はどうなりますか?(つまり、it
の値がn
未満の場合)
数年前に上記の行を書いたとき、おそらくStopIteration
にはリスト内包表記をきれいに終了するという巧妙な副作用があると思いました。しかし、いいえ、全体の理解はStopIteration
を上向きに渡すとクラッシュします。 (例外がrange(n)
イテレータから発生した場合にのみ、正常に終了します。)
これはおそらくあなたが望む振る舞いではありません。
しかし、それはさらに悪化します。以下はリスト内包表記と同等であると想定されています(特にPython 3):
_list(next(it) for _ in range(n))
_
そうではありません。内側の部分はジェネレーター関数の省略形です。 list()
は、StopIteration
anywhereを発生させたときに完了したことを認識します。
=>このバージョンは、n
値がない場合に安全に対処し、より短いリストを返します。 (itertools.islice()
のように。)
しかし、それも変わるでしょう!ジェネレーター内のコードがStopIteration
を発生させると、ジェネレーターがサイレントに終了するという事実は、 PEP 479 で対処される既知の疣贅です。 Python 3.7(または将来のインポートでは3.5)から、ジェネレーターをクリーンに終了する代わりにRuntimeError
が発生します。つまり、リスト内包表記の動作に似たものになります。 (最近のHEADビルドでテスト済み)
for Word, i in Zip(Word_reader(file), xrange(n)):
...
ジェネレーターの最初のn個の値を取得するには、 more_itertools.take を使用できます。
チャンク内の単語(たとえば、一度に100)を反復処理する場合は、more_itertools.chunked( https://more-itertools.readthedocs.io/en/latest)を使用できます。 /api.html ):
import more_itertools
for words in more_itertools.chunked(reader, n=100):
# process 100 words
cytoolz.take を使用します。
>>> from cytoolz import take
>>> list(take(2, [10, 20, 30, 40, 50]))
[10, 20]