Generators are special functions that implement or generate iterators. Generators are functions which behave like iterators, but can have better performance characteristics. These include:

  • Creating values on demand, resulting in lower memory consumption.
  • The values returned are lazily generated. Hence, it is not necessary to wait until all the values in a list are generated before using them.

However, the set of generated values can only be used once.

Generators look like normal functions, but instead of the return statement they make use of the yield statement.cThe yield statement tells the interpreter to store local variables and record the current position in the generator, so when another call is made to the generator, it will resume from that saved location and with the previous values of local variables intact.

Consider this generator:

def test_generator():
    yield 1
    yield 2
    yield 3

g = test_generator()

We can now iterate over g using the next() function:

print(next(g)) # 1
print(next(g)) # 2
print(next(g)) # 3
print(next(g)) # StopIteration error