Roman
Roman

Reputation: 617

Please explain Generator mechanics in this example

Can someone explain the mechanics of why it prints only 3 lines, instead of 24. I know its due to the fact that the generator function is exhausted, but how?

def counter_gen(size):
    cur=1
    while cur <= size:
        yield cur
        cur +=1

c1=counter_gen(8)
c2=counter_gen(3)

for x in c1:
    for y in c2:
        print x,y

Upvotes: 1

Views: 186

Answers (2)

kindall
kindall

Reputation: 184171

c2 reaches its end after 3 iterations. Iterating on it again will do nothing. That's what's meant by "exhausting" the iterator. So, after three items, it stops. Your outer iterator goes 8 times, but because the inner iterator only goes 3 times, only the first outer iteration does anything. The next 7 try to iterate over the exhausted iterator, and nothing happens.

If you want a new iteration of c2 to start with each iteration of c1, simply write it that way!

c1=counter_gen(8)

for x in c1:
    c2=counter_gen(3)
    for y in c2:
        print x, y

Or, do away with the c1 and c2 entirely:

for x in counter_gen(8):
    for y in counter_gen(3):
        print x, y

Upvotes: 5

David Cain
David Cain

Reputation: 17333

c1 and c2 are generator objects. You can iterate over them once, then further calls to next() will raise StopIteration. Playing around in an interpreter should give you an idea of what's happening:

>>> c1 = counter_gen(3)
>>> for item in c1:
        pass
>>> c1.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> [i for i in c1]  # Exhausted, will immediately raise StopIteration
[]

Try creating a new generator in the body of the loop instead:

for x in counter_gen(8):
    for y in counter_gen(3):
        print x,y

Upvotes: 1

Related Questions