Python Generators and yield: Lazy Iteration Explained
A Python generator is an iterator that produces values as you request them. Use yield to pause a function and give its caller a value.
Read Iterators first.
Yield a value and pause
Calling a generator function creates a generator. Its body starts when you request a value.
def steps():
print("starting")
yield 1
print("resuming")
yield 2
iterator = steps()
print("created")
print(next(iterator))
print(next(iterator))
created prints before starting. Each next() resumes execution until the next yield.
Generate values with a loop
The generator remembers local variables between requests. You can consume it with a for loop.
def countdown(start):
while start > 0:
yield start
start -= 1
for number in countdown(3):
print(number)
This prints 3, 2, then 1 without building a list of all the results.
End with return
yield pauses the function; return ends it. Reaching the end also stops the generator.
def before_zero(numbers):
for number in numbers:
if number == 0:
return
yield number
iterator = before_zero([4, 7, 0, 9])
print(list(iterator))
print(list(iterator))
The first list is [4, 7]. The second is empty because the generator is exhausted.
Note: Lazy iteration avoids storing every result at once. Calling list() on a generator stores all its remaining results.
See also: Generator expressions, Parameters and return.
Your turn
Add two indented yield lines to produce 5, then 10.
def bonuses():
# add two lines: yield 5, then yield 10
pass
print(list(bonuses()))
Expected output
[5, 10]