yield
¶A Python generator
is a special type of Python function can 'return' multiple values sequentially.
return
keywordyield
keywordRegular Python functions don't have a persistent 'memory'. They only get one chance to do all their calculations and return one final results when they are done. Here are some situations in chemical engineering where Python generators might be useful:
Further reading:
A generator is defined the same way as a function, using def
. If the function contains a yield
statement, it automatically becomes a generator.
def generator_function():
yield 1
yield 2
yield 3
There are 2 ways to get values from a generator:
next()
keywordsend()
keyword, which allows us to send values back to the generator and manipulate the sequence# Create our generator object
print_numbers = generator_function()
print_numbers
<generator object generator_function at 0x10bd63f10>
next(print_numbers)
1
next(print_numbers)
2
next(print_numbers)
3
# We will get an error since there are no more values to return
next(print_numbers)
---------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-6-8ea3ba4c796c> in <module>() 1 # We will get an error since there are no more values to return ----> 2 next(print_numbers) StopIteration:
We saw earlier that we can yield numbers by doing yield 1
, yield 2
and yield 3
.
Let's try something different by doing a = yield 1
. This line means that we'll yield 1
and when the generator receives a value from send()
, it will store it in a
.
def second_generator():
a = yield 10
b = yield (a+10)
yield (b+20)
Here's how to get the values
# Create our generator object
print_stuff = second_generator()
print_stuff
<generator object second_generator at 0x10be4cfc0>
# When we are sending stuff to a generator for the first time, we need to use `None`. This would yield 10.
print_stuff.send(None)
10
# The next line would store 10 in a, and then yield a+10 = 20
print_stuff.send(10)
20
# The last line would store 10 in b, and then yield b+20
print_stuff.send(10)
30
# There are no more values to yield, so we'll get an error
print_stuff.send(None)
---------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-12-6c638364436d> in <module>() 1 # There are no more values to yield, so we'll get an error ----> 2 print_stuff.send(None) StopIteration: