Question about yield
Steven D'Aprano
steve at pearwood.info
Mon Nov 16 08:10:20 EST 2015
On Sun, 15 Nov 2015 01:37 pm, fl wrote:
> Hi,
> I have read a couple of tutorial on yield. The following code snippet
> still gives me a shock. I am told yield is a little like return. I only
> see one yield in the tutorial examples. Here it has two yields. And there
> are three variables following keyword yield.
Correct. `yield` exits the running function, but unlike `return`, the
function doesn't close down, it just pauses, ready to start up again when
you call next() on it.
Here is an example of an ordinary function:
py> def function():
... return 1
... return 2
... return 3
...
py> function()
1
py> function()
1
Each time you call the function, it starts again at the beginning, and exits
after the first `return`. So the lines `return 2` and `return 3` are dead
code that never gets run.
Here is an example of a generator function with yield. Calling generators is
a bit different from calling a function: first you have to initialise them
by calling the function to create a "generator object", then you call the
next() function to advance to the next `yield` statement, and finally they
raise an exception when there are no more `yields`.
An example might help:
py> def generator():
... yield 1
... yield 2
... yield 3
...
py> gen = generator()
py> next(gen)
1
py> next(gen)
2
py> next(gen)
3
py> next(gen)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
To start the generator from the beginning again, you have to create a new
generator object by calling the function:
gen = generator()
Calling next() many times is often inconvenient. Normally you will iterate
over the generator:
for x in gen:
print(x)
or you call collect all the items using list(). See example below.
Here is a generator which takes a list as argument, and returns a running
sum of the list values:
def running_sum(alist):
total = 0
for value in alist:
total += value
yield total
And here is an example of using it:
py> gen = running_sum(data)
py> list(gen)
[1, 3, 6, 16, 18, 18, 23]
--
Steven
More information about the Python-list
mailing list