Instantly share code, notes, and snippets.

# Atlas7/python_generator_yield.md Last active Jan 12, 2018

Python Generator and Yield - Example

This example illustrate the use of Python generator. (it's like callback function in JavaScript - sort of.)

# Example 1

Create a matrix and print result:

```M = [[1,2,3],    # this row sum to 6
[4,5,6],    # this row sum to 15
[7,8,9]]    # this row sum to 24

print(M)
# -> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]```

Create a Python generator and print result:

```G = (sum(row) for row in M) # create a generator of row sums
print(G)
# <generator object <genexpr> at 0x116810258>```

Run the iteration protocol:

```print(next(G)) #
# -> 6```

again...

```print(next(G)) #
# -> 15```

again...

```print(next(G)) #
# -> 24```

As we see, each `next()` activate the Generator compute values and forget on the fly.

# Example 2

Create a matrix and print result:

```M = [[1,2,3],    # this row sum to 6
[4,5,6],    # this row sum to 15
[7,8,9]]    # this row sum to 24

print(M)
# -> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]```

Create a new generator - use this as a syntatic sugar:

```G = (row for row in M)
print(G)
# -> <generator object <genexpr> at 0x1167460f8>

for a in G:
print(a)

#    [1, 2, 3]
#    [4, 5, 6]
#    [7, 8, 9]```

# Example 3

Illusrate Python Yield statement.

Say we want to print the first `n` fibonacci numbers. Use yield to compute the new fibonacci number, forget the old one right away, to save memory. (i.e. we compute and forget on the fly).

Define the function:

```def fibonacci(n):
curr = 1
prev = 0
counter = 0
while counter < n:
yield curr
prev, curr = curr, prev + curr
counter += 1```

Create a generator.

```G = fibonacci(10)
print(G)
# <generator object fibonacci at 0x116716f68>```

Compute the 1st fibonacci number on the fly, and forget straight away afterwards.

```print(next(G))
# 1```

Compute the 2nd fibonacci number on the fly, and forget straight away afterwards.

```print(next(G))
# 1```

Compute the 3rd fibonacci number on the fly, and forget straight away afterwards.

```print(next(G))
# 2```

4th fibonacci number...

```print(next(G))
# 3```

5th fibonacci number...

```print(next(G))
# 5```

6th fibonacci number...

```print(next(G))
# 8```

7th fibonacci number...

```print(next(G))
# 13```

8th fibonacci number...

```print(next(G))
# 21```

9th fibonacci number...

```print(next(G))
# 34```

10th fibonacci number...

```print(next(G))
# 55```

We are done. If we try this step again...

`print(next(G))`

We will get an error saying we are exceeding our iteration limit:

``````    ---------------------------------------------------------------------------

StopIteration                             Traceback (most recent call last)

<ipython-input-64-cccebc38bfde> in <module>()
----> 1 print(next(G))

StopIteration:

``````

# Conclusion

This post summarises some typical usage of Python Generator and yield.

# Reference