In summary, the yield
statement transforms your function into a factory that produces a special object called a generator
which wraps around the body of your original function. When the generator
is iterated, it executes your function until it reaches the next yield
then suspends execution and evaluates to the value passed to yield
. It repeats this process on each iteration until the path of execution exits the function. For instance;instance,
def simple_generator():
yield 'one'
yield 'two'
yield 'three'
for i in simple_generator():
print i
simply outputs ;
one
two
three
The power comes from using the generator with a loop that calculates a sequence, the generator executes the loop stopping each time to 'yield' the next result of the calculation, in this way it calculates a list on the fly, the benefit being the memory saved for especially large calculations
Say you wanted to create a your own range
function that produces an iterable range of numbers, you could do it like so,
def myRangeNaive(i):
n = 0
range = []
while n < i:
range.append(n)
n = n + 1
return range
and use it like this;
for i in myRangeNaive(10):
print i
butBut this is ineffecientinefficient because
- You create an array that you only use once (this wastes memory)
- This code actually loops over that array twice! :(
Luckily Guido and his team were generous enough to develop generators so we could just do this;
def myRangeSmart(i):
n = 0
while n < i:
yield n
n = n + 1
return
for i in myRangeSmart(10):
print i
Now upon each iteration a function on the generator called next()
executes the function until it either reaches a 'yield' statement in which it stops and 'yields' the value or reaches the end of the function. In this case on the first call, next()
executes up to the yield statement and yield 'n', on the next call it will execute the increment statement, jump back to the 'while', evaluate it, and if true, it will stop and yield 'n' again, it will continue that way until the while condition returns false and the generator jumps to the end of the function.