Vraag Waarom wordt list (next (iter (())) voor _ binnen het bereik (1)) == [] geplaatst?


Waarom doet list(next(iter(())) for _ in range(1)) retourneer een lege lijst in plaats van verhogen StopIteration?

>>> 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))  # ?!
[]

Hetzelfde gebeurt met een aangepaste functie die expliciet verhoogt 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))  # ?!
[]

17
2017-08-29 20:49


oorsprong


antwoorden:


ervan uitgaande dat alles goed gaat, het begrip van de generator x() for _ in range(1) moet verhogen StopIteration wanneer het klaar is met itereren range(1) om aan te geven dat er geen items meer in de lijst mogen worden ingepakt.

Maar omdat x() raises StopIteration het eindigt met het verlaten van de vroege betekenis van dit gedrag is een bug in python die wordt aangepakt PEP 479

In python 3.6 of met from __future__ import generator_stop in python 3.5 wanneer een StopIteration verder uitpropageert, wordt het omgezet in een RuntimeError zodat list registreert het niet als het einde van het bevattingsvermogen. Wanneer dit van kracht is, ziet de fout er als volgt uit:

Traceback (most recent call last):
  File "/Users/Tadhg/Documents/codes/test.py", line 6, in <genexpr>
    stuff = list(x() for _ in range(1))
  File "/Users/Tadhg/Documents/codes/test.py", line 4, in x
    raise StopIteration
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/Tadhg/Documents/codes/test.py", line 6, in <module>
    stuff = list(x() for _ in range(1))
RuntimeError: generator raised StopIteration

9
2017-08-29 21:07



De StopIteration uitzondering wordt gebruikt om het onderliggende mechanisme van de list functioneer wanneer je moet stoppen met itereren op de iterable die eraan is doorgegeven. In jouw geval vertel je Python dat het ding dat is doorgegeven list() is een generator. Dus wanneer het dat krijgt, geeft het een lege lijst af omdat er niets is verzameld.


6
2017-08-29 20:51