Hacker News new | past | comments | ask | show | jobs | submit login
Python iterators: wat (pound-python.org)
6 points by anaphor on July 6, 2018 | hide | past | favorite | 1 comment



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.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: