2016-08-29 4 views
17

なぜlist(next(iter(())) for _ in range(1))は、StopIterationを呼び出すのではなく、空のリストを返しますか?なぜrange(1)の_のnext(iter(()))== []ですか?

>>> next(iter(())) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 
>>> [next(iter(())) for _ in range(1)] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 
>>> list(next(iter(())) for _ in range(1)) # ?! 
[] 

同じことが明示的にStopIterationを上げるカスタム関数で発生します:

>>> def x(): 
...  raise StopIteration 
... 
>>> x() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in x 
StopIteration 
>>> [x() for _ in range(1)] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in x 
StopIteration 
>>> list(x() for _ in range(1)) # ?! 
[] 
+1

私は本当に元の「重複した」質問の答えが好きです! – wheaties

+3

これはバグです。[PEP 479](http://legacy.python.org/dev/peps/pep-0479/)で対処されています。ここで 'StopIteration'は' RuntimeError'に変換されます。あなたが期待しているとおり、リストは反復を間違って停止しません。 –

+1

@ TadhgMcDonald-Jensen私はそれを投票することができるように答えてください。 – wheaties

答えて

9

すべてがうまくいくと仮定して、range(1)を反復して終了すると、生成者の理解x() for _ in range(1)は、StopIterationを生成してリストにパックする項目がないことを示します。しかし

x()が、それはこの動作が呼び出すとStopIterationが遠く、それが変換されて伝播する際のpython 3.5でのpython 3.6またはfrom __future__ import generator_stopを使用してPEP 479

で対処しているのpythonのバグである早期の意味を出て終わるStopIteration上げるため、 listが理解の終わりとしてそれを登録しないようにRuntimeErrorに。これが有効になっている場合、エラーは次のようになります。

​​
6

実際にその反復可能で反復処理を停止するときStopIteration例外がlist機能の根底にあるメカニズムを伝えるために使用されていますそれに渡されました。あなたの場合、list()に渡されたものがジェネレータであることをPythonに伝えています。だからそれが得られれば、何も蓄積されていないので空リストを出力します。

+0

間違っていると、 'for _ in range(1)'からの反復反復は、リストの終了のための 'StopIteration'を発生させるべきですが、' x() 'は、 *誤って停止する原因となります。これはpython3.6で変更されており、python 3.5の 'from __future__ import generator_stop'で使用できます。 [PEP 479](http://legacy.python.org/dev/peps/pep-0479/)を参照してください。 –

+2

@ TadhgMcDonald-Jensen固定されているのはうれしいですが、それはバグだから変わらないそれがまさに何が起こっているのかという事実です。 – wheaties

+0

@ TadhgMcDonald-Jensen私は小麦の答えが間違っているとは言いません。しかし、あなたが答えとしてそれを投稿できるなら、私はそれを喜んで受け入れます。 –

関連する問題