def squares_listsquare_list(n):
the_list = [] # Replace
for x in range(n):
y = x * x
the_list.append(y) # these
return the_list # lines
def squares_the_yield_waysquare_yield(n):
for x in range(n):
y = x * x
yield y # with this one.
yield
is a sugarysugary way to say
>>> for square in squares_listsquare_list(4):
... print(square)
...
0
1
4
9
>>> for square in squares_the_yield_waysquare_yield(4):
... print(square)
...
0
1
4
9
Yield is single-pass: you can only iterate through once. When a function has a yield in it we call it a generator function. And an iterator is what it returns. That'sThose terms are revealing. We lose the convenience of a container, but gain the power of ana series that's computed as needed, and arbitrarily long series.
Yield is lazy, it puts off computation. A function with a yield in it doesn't actually execute at all when you call it. when you call it. The iterator object itIt returns usesan magic to maintain the function's internal contextiterator object that remembers where it left off. Each time you call next()
on the iterator (this happens in a for-loop) execution inches forward to the next yield. (return
raises StopIteration
StopIteration and ends the series. (this is the natural end of a for-loop).
Yield is versatile. Data doesn't have to be stored all together, it can be made available one at a time. It can dobe infinite loops:.
>>> list(squares_the_yield_waysquare_yield(4))
[0, 1, 4, 9]