Sherafati
Sherafati

Reputation: 216

Problem with iterating generator functions

Let's say we have this generator function:

def count_up_to(max):
    count = 1
    while count <= max:
        yield count
        count += 1

Now if I want to call the next() function, I will have to assign the count_up_to function to a variable, otherwise the output will always be "1".

The code below works fine and iterates through the numbers:

counter = count_up_to(10)
print(next(counter))
print(next(counter))
print(next(counter))
.
.
.

But this one does not work and keeps printing "1".

print(next(count_up_to(10)))
print(next(count_up_to(10)))
print(next(count_up_to(10)))
.
.
.

But why? is print(next(counter)) any different from print(next(count_up_to(10))) ?!

Upvotes: 1

Views: 126

Answers (2)

Dmitry Egerev
Dmitry Egerev

Reputation: 516

It's completely expected behavior. Lets me describe why.

Every single call of count_up_to will return you a new generator, which starts from 1.

Simple check in Python REPL:

>>> count_up_to(100)
<generator object count_up_to at 0x10e28beb0>
>>> count_up_to(100)
<generator object count_up_to at 0x10e28bf00>
>>> count_up_to(100)
<generator object count_up_to at 0x10e28beb0>
>>> count_up_to(100)
<generator object count_up_to at 0x10e28bf00>

Look at the address. It is always different, there are 4 different generators in memory.

So, count_up_to function is not a generator itself, but it returns a generator when you call it.

And when you stores result of count_up_to call in a variable, you store generator. Further, you can get values from the generator, stored in the variable.

Upvotes: 2

Rafael
Rafael

Reputation: 574

In your last snippet, you always make a new generator, that's why it always prints "1".

In the second one, you assign the generator returned by count_up_to to the variable count, not the function. And with every call of next(count), you tell the generator to yield the next value.

I hope that this helps :)

Upvotes: 3

Related Questions