How to use generator in Python with examples
In this module, we will learn how to use generator in Python with examples.
What is a generator?
A generator in Python is nothing but a function with its unique ability. In simple terms, generators are a different kind of iterators which returns the values one at a time and only when asked. But why do we need generators? Generator functions are memory efficient as they do not hold any values. They are hence very useful when handling large streams of data.
To create a generator, we need a yield statement and next() method. The yield statement is used instead of usually used return statement; it returns some value from a function. But unlike return statement, instead of terminating the entire function in one go, yield statement returns values one at a time. It pauses and holds one value at a time. So they let us do the calculations whenever we want which is also known as lazy evaluation. The next time yield statement is called, it resumes execution from it’s last generated result and not the beginning.
The next() method calls the yield statement in order to get its values. It is similar to asking, “What should be iterated next?” Hence, every time next() is called it resumes its execution from when the last yield was executed. In this way, next() is used to get next value from the generator.
Let us illustrate this with an example.
Use of generator in Python
This is a simple example of a generator:
def gen(): yield 1 yield 2 yield 3 yield 4 x = gen() print(x.__next__()); print(x.__next__());
Here, a generator function gen() is defined and 1, 2, 3 and 4 is yielded. Using next() method twice, we get the output as:
Similarly, to get all the values, we can use next() method 4 times.
def gen(): yield 1 yield 2 yield 3 yield 4 x = gen() print(x.__next__()); print(x.__next__()); print(x.__next__()); print(x.__next__());
1 2 3 4
Now, on further calls, a StopIteration exception is raised since iteration in the function has been terminated. The error would look something like this:
Traceback (most recent call last): ... StopIteration
Since generator is a form of iterator, “for” loop can be implemented. Generators are in fact very compatible with “for” loop because of it’s method of generating one-at-a-time results. Let us revise the above code using “for” loop:
def gen(): yield 1 yield 2 yield 3 yield 4 for x in gen(): print(x)
Generator expressions can also be written in a similar manner as list comprehensions. The syntax is the same but instead of a square bracket, parenthesis is used. Our above code can be modified to appear like a list like:
gen = (x for x in range(5)) print(list(gen))
[0, 1, 2, 3, 4]
Some more examples of generators:
Example 1: To print the square of first 5 numbers using generators in Python
def square(): for x in range(5): yield (x*x) for val in square(): print(val)
0 1 4 9 16
Example 2: To print sum of first 5 numbers using generator expression in Python
gen = (x for x in range(5)) print(sum(gen))
Example 3: To generate Fibonacci series using generators in Python
def fibonacci(a=0, b=1): while True: yield a a, b = b, a+b x = fibonacci() for i in range(10): print(x.__next__())
0 1 1 2 3 5 8 13 21 34
- Generator functions contain yield statements which are used instead of return statements.
- During execution, when called, it returns a generator object.
- Iterations through data are done using the next() method.
- Once yielded, it returns the values one at a time.
- yield remembers it’s the last state and continues from that point when called.
- Finally, when the function terminates, StopIteration is raised.