Reputation: 402
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:
Upvotes: 8
Views: 4912
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
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