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.
`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.
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.