Python Generators with Examples

FREE Online Courses: Knowledge Awaits – Click for Free Access!

A generator is a kind of function that returns an object called a generator object which can return a series of values rather than a single value. Generators are typically defined with the def keyword. A generator must have at least one yield statement. A Generator can have more than one yield statement. A generator returns a generator object which is similar to an iterator object.

Creating a Generator in Python

Creating a generator is similar to creating a function. We use the keyword def and a yield statement to create a generator.

Let us create a generator that prints the first 50 natural numbers.

Example of creating a generator in Python

def natural_numbers():
   num = 1
   while num <= 50:
       yield num
       num += 1

print(natural_numbers())

Output

<generator object natural_numbers at 0x1063984a0>

next() and __next__() with Generators in Python

In the previous code example, we can see that calling a generator creates a generator object rather than getting the required value. To get values from a generator, we can use either next() or __next__() on the resultant generator object.

Example of next() in Python

my_numbers = natural_numbers()

print(next(my_numbers))
print(next(my_numbers))
print(next(my_numbers))

Output

1
2
3

Example of __next__() in Python

my_numbers = natural_numbers()

print(my_numbers.__next__())
print(my_numbers.__next__())
print(my_numbers.__next__())

Output

1
2
3

We can also use both next() and __next__() together.

Example of next() and __next__() in Python

my_numbers = natural_numbers()

print(next(my_numbers))
print(next(my_numbers))
print(my_numbers.__next__())
print(my_numbers.__next__())

Output

1
2
3
4

Generator with For-Loop in Python

Instead of writing a line for each value, Python allows us to write a simple for-loop to get all values from a generator.

Example of using loop in Python

for number in natural_numbers():
   print(number)

Output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

In the above code example, the simple two lines of code printed all the values generated by the generator natural_numbers()

Generator with Multiple yield Statements

To make things even more interesting, We can use more than one yield statement in a generator. The yield statements are executed sequentially. A second yield statement will execute only after the completion of the first yield statement.

Example of multiple yield statements in a generator

def my_generator():
   yield "Python"
   yield "Geeks"
   yield "PythonGeeks"

for val in my_generator():
   print(val)

Output

Python
Geeks
PythonGeeks

Generators and list() in Python

We often need to save the generated values in a list. This we can normally do by using a for-loop and an append statement but Python offers an even better solution. We can apply the list() function on a generator object to store all generated values at once in a list.

Example of using list() in Python

values = list(my_generator())
print(values)

Output

[‘Python’, ‘Geeks’, ‘PythonGeeks’]

Python Generator Expressions

In python, there is a simpler way for creating generators. Instead of creating a generator similar to a function, we can create a generator similar to list comprehension. The only difference is that to create a list comprehension, we use square brackets whereas to create a generator object, we use parentheses.

Example of generator expression in Python

natural_numbers = (n for n in range(1, 25))
print(natural_numbers)

Output

<generator object <genexpr> at 0x10f78c4a0>

Now we can use any of the previously mentioned methods for getting values from the generator. In this case, let us use a list() function.

Example of generator expression in Python

natural_numbers = (n for n in range(1, 25))
my_numbers = list(natural_numbers)
print(my_numbers)

Output

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]

Memory Usage of Generators in Python

One of the main advantages of generators is their high memory conservation. Generators only store one value at a time in memory. Even if we are generating a hundred numbers, we only utilize the memory required for one number. This greatly decreases the memory complexity of our program and enables us to utilize the saved memory for other useful tasks.

Handling Infinite Data with Generators

While working with large amounts of data or infinite data like generating infinite numbers, we can use generators to store one value at a time.

Example of generating infinite numbers in Python

def infinite():
   num = 1
   while True:
       yield num
       num += 1

for n in infinite():
   print(n)

Output

1
2
3
.
.
.

The output goes on infinitely.

StopIteration in Python

When a generator runs out of values to yield, Python raises a StopIteration error.

Example of StopIteration in Python

def my_generator():
   for i in range(3):
       yield i

obj = my_generator()
print(next(obj)) # 1
print(next(obj)) # 2
print(next(obj)) # 3
print(next(obj)) # StopIteration

Output

0
1
2
StopIteration

Interview Questions on Generators in Python

Q1. Create a generator to print multiples of 12.

Ans 1. Complete code is as follows:

def multiples():

   num = 1
   while True:
       multiple = num * 12
       yield multiple
       num += 1

Q2. Create a generator to print the first five even natural numbers followed by the first six odd natural numbers.

Ans 2. Complete code is as follows:

def even_odd():

   for n in range(2, 11, 2):
       yield n

   for n in range(1, 11, 2):
       yield n

Q3. Create a generator to print all 26 alphabets in smaller cases using the generator expression.

Hint: chr(97) = ‘a’

Ans 3. Complete code is as follows:

alphabets = list((chr(i) for i in range(97, 123)))
print(alphabets)

Q4. Print the first 4 values yielded by a generator named some_generator() without using any loops in Python.

Ans 4. Complete code is as follows:

obj = some_generator()
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))

Q5. Print all values yielded by a generator named some_generator() without using any loops in Python. Use only one print statement in your code.

Ans 5. Complete code is as follows:

values = list(some_generator())
print(values)

Quiz on Python Generators

Conclusion

In this article, we learned the implementation of generators. We learned multiple ways of yielding values from a generator. Then we discussed how efficient a generator is and the errors raised by generators. Furthermore, if you have any queries, please express them in the comments section.

Your opinion matters
Please write your valuable feedback about PythonGeeks on Google | Facebook


1 Response

  1. Suchi says:

    Hi,

    Needless to say what an efficient way you covered all concepts about generator. Specially your quiz also. From your quiz I came to know this is another way of writing multiple next generator object in a single line and that always execute the first yield value only. I know that generator execute only one yield stat at a time but when we print multiple next method to call generator object then why only one object value is returned. pls share some thoughts on it. Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *