私はPythonのジェネレータ、イテレータ、iterablesを学習しています。なぜ次のものが動作しないのか説明できません。私は、エクササイズとして関数zipの簡単なバージョンを作成したいと考えています。ここに私がやったことだ:ジェネレータのStopIteration
def myzip(*collections):
iterables = tuple(iter(collection) for collection in collections)
yield tuple(next(iterable) for iterable in iterables)
test = myzip([1,2,3],(4,5,6),{7,8,9})
print(next(test))
print(next(test))
print(next(test))
私は何をすることです:
- 私は
collections
を持っている私は、コレクションごとに新しいタプルiterables
、(作成いくつかのコレクションのタプル - ありますiterable)を使用して、イテレータを取得します。
iter
- 次に、各繰り返しで、
next
という新しいタプルを作成します。このタプルは次に収穫です。
最初の実行時にオブジェクトiterables
が作成(および保存)されることが期待されます。その後、各繰り返し(最初のものを含む)で、私はnext
を呼び出す前にすべてのiterableを呼び出して、それを返します。
しかし、これは私が得るものです:
(1, 4, 8)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-108-424963a58e58> in <module>()
8
9 print(next(test))
---> 10 print(next(test))
StopIteration:
は、だから私は、最初の繰り返しで結構ですし、結果が正しいことがわかります。しかし、2回目の反復ではStopIteration例外が発生します。理由はわかりません。各反復可能にはまだ値があるため、next
のどれもStopIterationを返しません。実際には、これは動作します:
def myziptest(*collections):
iterables = tuple(iter(collection) for collection in collections)
for _ in range(3):
print(tuple(next(iterable) for iterable in iterables))
test = myziptest([1,2,3],(4,5,6),{7,8,9})
出力:
(1, 4, 8)
(2, 5, 9)
(3, 6, 7)
だから何が起こっているの? どうもありがとう
これは本当に愚かな間違いだった...私はサイクルを追加するのを忘れていたので、関数が最初のnext()の後ではっきりと死んだ。 ありがとうございます! – edoedoedo
問題ありません。参考までに、コレクションが同じサイズでなくても、 'tuple(iterable in iterables in iterables) 'は引き続き動作します。それを 'tuple(iterableでiterableのためのnext(iterable))'にするとStopIterationがトリガーされるので、最短の共通長で停止することができます。 – algrebe
実際、テスト中であれば、print(i) '私は無限ループを起こします。違いは何ですか? – edoedoedo