# yield

By Brian Fitzgerald

Here are my observations on python yield.

The presence of “yield” causes a function to become a factory of generators.  Here is an example.

```def fgen():
p, f = 1, 1
print('initial p=%s p=%s ' % (p, f))
while True:
print('y %s' % f)
yield f
p, f = f, p + f
print('next p=%s f=%s' % (p, f))```

Now we will run it. The call:

```fa = fgen()
print('g %s' % fa)
for fi in fa:
print('ret A %s' % fi)
if fi >= 5:
break```

The output:

```g <generator object fgen at 0x00C280C0>
initial p=1 p=1
y 1
ret A 1
next p=1 f=2
y 2
ret A 2
next p=2 f=3
y 3
ret A 3
next p=3 f=5
y 5
ret A 5```

Notes:

• The call fa = fgen() produced no output. No fgen code ran.
• fgen’s return type is generator. fa is a generator.
• “for i in fa:” causes the generator to iterate.
• In the first iteration, the “print(‘initial…” statement ran.
• When execution reached “yield f”, the generator returned f and returned control to the caller. That is evident from this output:
```y 1
ret A 1```
• On the second iteration, generator execution picked up where it left off, and ran
`p, f = f, p + f`

output:

`next p=1 f=2`

Note that f values are generated on the fly whenever the generator is called.

If the same generator (“fa”) gets used again, like this:

```for fi in fa:
print('ret A+ %s' % fi)
break```

then the generator picks up where it left off:

```next p=5 f=8
y 8
ret A+ 8```

Calling fgen again gets a new generator that starts from scratch.

```fb = fgen()
print('g %s' % fb)
for fi in fb:
print('ret B %s' % fi)
if fi >= 3:
break```

Output:

```g <generator object fgen at 0x02DE81B0>
initial p=1 p=1
y 1
ret B 1
next p=1 f=2
y 2
ret B 2
next p=2 f=3
y 3
ret B 3```

Summary:

• “yield” is used to define a function that returns a generator.
• On the first call to the generator, execution runs up to the yield.
• On subsequent calls, execution continues where it left off.