[Tutor] I am having difficulty grasping 'generators'

Danny Yoo dyoo at hashcollision.org
Wed May 28 03:08:45 CEST 2014


On Tue, May 27, 2014 at 12:27 PM, Degreat Yartey
<yarteydegreat2 at gmail.com> wrote:
> I am studying python on my own (i.e. i am between the beginner and
> intermediate level) and i haven't met any difficulty until i reached the
> topic 'Generators and Iterators'.
> I need an explanation so simple as using the expression 'print ()', in this
> case 'yield'.


You can think of a generator as almost like a function, except it can
return, not just once, but multiple times.


Because it can return multiple times, if we squint at it enough, it
acts like a _sequence_, just like the other sequence-like things in
Python like files and lists and tuples.  That is, as a sequence, it's
something that we can walk down, element by element.  We can loop over
it.


For example, let's say that we wanted to represent the same sequences
as that of range(5).  Here's one way we can do it with a generator:

#################
def upToFive():
    yield 0
    yield 1
    yield 2
    yield 3
    yield 4
#################


Let's try it.

#################
>>> sequence = upToFive()
>>> next(sequence)
0
>>> next(sequence)
1
>>> next(sequence)
2
>>> next(sequence)
3
>>> next(sequence)
4
>>> next(sequence)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>
>>>
>>> for x in upToFive():
...     print("I see %d" % x)
...
I see 0
I see 1
I see 2
I see 3
I see 4
#################


Now this is a toy example.  If we wanted range(5), we'd just say
"range(5)" and be done with it.


What's neat about generators is that they make it easy to build these
sequences while pretending that we're writing a plain function.  All
of the even numbers, for examples, is a sequence that we can make with
a generator:

#################
def onlyEvens():
    n = 0
    while True:
        yield n
        n = n + 2
#################


Let's try running it:

#################
>>> sequence = onlyEvens()
>>> next(sequence)
0
>>> next(sequence)
2
>>> next(sequence)
4
>>> next(sequence)
6
#################

And note that this sequence doesn't stop!  We can keep calling next()
on it and it will continue to run.


We _can_ write a loop to run over such infinite sequences, but we'll
also have to make sure to stop it manually: it won't exhaust
otherwise, so doing something like:

#################
for n in onlyEvens():
    ...
#################

better have something in the "..." that interrupts or returns, or else
that loop will never end.


More information about the Tutor mailing list