GBeck
GBeck

Reputation: 402

When to use generator functions and when to use loops in Python

I am coming from a Matlab background and I am finding it difficult to get around the concept of generators in Python.

Can someone please answer me the following:

  1. The difference between a generator function and a loop
  2. When each should be implemented

Upvotes: 8

Views: 4912

Answers (2)

Bruno Vermeulen
Bruno Vermeulen

Reputation: 3465

Have a read in the following article How to Use Generators and yield in Python. Perhaps the following examples help a bit to understand to concept.

def my_range(n):
    for i in range(n):
        yield i

range_of_10 = my_range(10)
for i in range_of_ten:
    print(i)

result:

0
1
3
4
5
6
7
8
9

or

>>> range_of_ten = my_range(10)
>>> next(range_of_ten)
0
>>> next(range_of_ten)
1
etc.
>>> next(range_of_ten)
9
>>> next(range_of_ten)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

I like the following example where you can replace a double loop in one loop as follows:

def double_loop(n, m):
    for i in range(n):
        for j in range(m):
            yield i, j


n = double_loop(2, 4)
for i in n:
    print(i)

result

(0, 0)
(0, 1)
(0, 2)
(0, 3)
(1, 0)
(1, 1)
(1, 2)
(1, 3)

Upvotes: 1

Ofer Sadan
Ofer Sadan

Reputation: 11982

A generator provides a way to create elements "on the fly" without holding them all in memory before we start going over them. A loop is simply a way to make the generator, or another iterable, give us one element at a time.

For example:

for i in range(10):
    print(i)

The for block is a loop, and range is basically a generator. range doesn't create a list from 1-10 before the loop starts, it just creates the generator, the creator of these elements. You can also imagine range(1000000000000000000), which again wouldn't take any time to create (and won't take up memory) because none of the elements are created until they are needed.

On the other hand, our loop can also take one element from objects that already exist, like a list:

for i in [0,1,2,3,4,5,6,7,8,9]:
    print(i)

The same result would be printed, but the list is created and stored in its entriety before the loop starts. This means that while the loop is running, the list takes up memory space and time to create.

Both the examples are loops, but only the first one uses a generator.

This is just the basics, but there are more differences, like exceptions that can be raised and re-usability, iterating in parts, and more.

For more on the difference

EDIT: @Vicrobot is correct in stating that range isn't really a generator, but for the purposes of explaining the "laziness" of generators that's what I used for simplicity

Upvotes: 8

Related Questions