5. What is wrong there?
The code is quite simple and straightforward, but its builds the full list in memory. This is clearly not acceptable in our case,
because we cannot afford to keep all n "10 megabyte" integers in memory.
10. Yield is a keyword that is used like return, except the function will return a
generator.
11. When a yield statement is executed, the state of the generator is frozen and the
value of expression_list is returned to next()‘s caller. By “frozen” we mean that all
local state is retained, including the current bindings of local variables, the
instruction pointer, and the internal evaluation stack: enough information is saved
so that the next time next() is invoked, the function can proceed exactly as if the
yield statement were just another external call.
12. Iterators
It's a stateful helper object that will produce the next value when you call next() on
it. Any object that has a __next__() method is therefore an iterator. How it
produces a value is irrelevant.