Python generators are functions that allows lazy evaluation of data, .i.e. data is evaluated on-need basis. Unlike functions, which return the value and then stop executing, generators simply pause their execution and during the next call continue the execution where they left, return another value and pause again.
The simplest way of creating generators is using generator comprehensions, which follow the format of list comprehensions but are surrounded with round brackets:
A generator object is an iterable, i.e. it provides a method
next which calls
the next object of the iteration, or raises
StopIteration exception if there
isn’t any value left. Taking the example of
gc object that we created above:
Since it’s an iterable, it can be used directly in the loop constructs. To show
this example, we’ll have to create a new generator object. This is because once
the generator object raises
StopIteration, it can’t be used again, we have to
create a new object.
Generator comprehensions are one way of creating generators, the other one is to
create the generator functions. The generator function creates (and sends back)
a sequence of results instead of a single value. This is done by using the
yield statement instead of
The confusing point in the code snippet above can be how it returns the value more than once?
Well, the idea behind generators is that once it hits the
yield statement, it
returns that value, and pauses the execution of code. Next time the generator is
called, it starts executing the code once again.
Notice the while loop above, since the code is only paused and not stopped, it
restarts in the next iteration, increments the value of
next iteration of the loop yields value and pauses.
If we had used
return instead of
yield, the loop would have stopped either
after returning only one value, or we’d have to collect all the values in an
object and return that object.
While it won’t matter if the object is small and the values can be easily calculated but the use of generators is clearly advantageous when we have to defer the calculation of values, or the object returned will turn out to be huge.
For instance, reading a file which has millions of lines of text into a list is going to have large space requirements, but reading the same file into a generator, we can simply return one line of file at a time, taking down the memory required by a large amount.
Author Tushar Tyagi
LastMod Jan 14, 2015