
Python iterators: wat - anaphor
https://paste.pound-python.org/show/xlnI9t8bemWEQW1iViv4/
======
zephyrfalcon
I had to stare at this for a while before I figured it out.

`works` and `notworks` are both generators. They take an iterator (over a
list) and take two elements from it, then yield this. So when given [1,2,3,4]
you would expect to get back, [1,2], then [3,4], then StopIteration is raised.

`works` uses a list comprehension. It gets [1,2], [3,4], then there are fewer
than two elements left, so StopIteration is raised, the toplevel call wraps
the results in a list, and returns [[1,2], [3,4]].

`notworks` uses list() with _another generator_. This does look like it would
have the same behavior as the listcomp, but it does not. When we turn an
iterator/generator into a list, and the generator raises StopIteration, list()
will return a list of all the values produced so far. So it produces: [1,2],
[3,4], then [5], then endlessly [].

You can inspect the behavior by looping over the generator calls, e.g.

    
    
        for x in works(iter([1,2,3,4,5])):
            print(x)
    

tl;dr: In `works`, the StopIteration is handled by `works` itself, while in
`notworks` it is intercepted by the call to list(), rather than by `notworks`.
This causes the difference in behavior.

