Generators

If you were following the Iterators post, you could think that creating iterable object or generators (that could provide an iterator) in python is not so easy. You should be able to create a class, then implement those special methods, make sure everything works..
But there are easier ways.

Creating a Generator with the yield statement

  • The yield statement is used when you want to create a generator.
  • Here's an example:
 1def func_3():
 2    yield 'a'
 3    yield 'b'
 4    yield 'c'
 5
 6g = func_3()
 7print(type(g))
 8it = g.__iter__()
 9print(type(it))
10
11for item in it:
12    print(item)

When running this, you'll get the following output:

1<class 'generator'>
2<class 'generator'>
3a
4b
5c
  • Note that when you call the function it's content is not executed.
    Instead, you are getting a generator object.
  • You can get an iterator out of this object, then use it as you would use an iterator (for loop in this example)

Generator functions

  • A function with a yield statement is called a generator function
  • We could think of a generator function as a coroutine, as is demonstrated in the following example:
 1def func_3():
 2    yield 'a'
 3    yield 'b'
 4    yield 'c'
 5
 6g1 = func_3()
 7g2 = func_3()
 8
 9
10it1 = g1.__iter__()
11it2 = g2.__iter__()
12
13print(it1.__next__())
14print(it2.__next__())
15print(it1.__next__())

And the output of this will be:

1a
2a
3b
  • This example shows us trhat the function "execution" is:
    • paused
    • started again (before another "invocation" ends)
    • resumed as the definition of coroutines go.

We'll explore more about generators in future posts.