5) h. Generators and Generator Expressions

Earlier in the course you had a look at the range function and learned that it is a generator. In this chapter you will learn what that actually means.

Take a look at this example.

1
2
3
4
5
6
7
8
9
10
11
Output:
0
1
4
9
16
25
36
49
64
81




This generator is made to generate n squared numbers. As you have already noticed there is a new statement yield. The mere presence of this statement immediately tells Python that this function is a generator. But what does it do?

Well, it’s a little bit tricky. The statement yield yields control back to whoever has called the generator and gives the caller the current result. It means that every time a new value has been generated the generator stops, gives the value to the caller and lets him decide whether to continue generating values or not.

This is more efficient for both CPU and memory because you only generate values when they are needed and there is no waste.

Pause for a moment and imagine if you had a function that returned thousands of values but you actually wanted to use only the first 10 returned values.

You can see how generators save CPU because you could stop the for-loop midway after 10 values. Thus, your program wouldn’t have to actually generate thousands of values.

Also, since generators return values back iteratively they consume less working memory each time as compared to a normal function which would return back a bunch of values all at once.



You can express simple generators like this in a more convenient way as a generator expression. Note this pythonic way of creating a function by using a single line of code. When you write a function this way Python automatically considers the return as a yield statement.

1
2
3
4
5
6
Output:
0
1
4
9
16



This looks a lot like a list comprehension but note that here you use the parenthesis instead of brackets. Hence, this is a generator.

Note: You need to be very careful with the brackets. If you replaced the parenthesis with square brackets then you would end up creating a list instead.