1

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))) ?!

2
  • 2
    On your last snippet, you're initialising your generator anew for every print line, so every next() call gets a fresh new iterator. Commented Apr 28, 2020 at 20:32
  • 2
    of course it's different. In the first case, you create one generator object and keep re-using it. In the second case, you create a new generator object each time you use it. You seem to have already discovered this? What exactly do you not understand? Commented Apr 28, 2020 at 20:35

2 Answers 2

3

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 :)

Sign up to request clarification or add additional context in comments.

5 Comments

But using a for loop with the function name works: for num in count_up_to(10): print(num). as far as i know the for loop keeps calling the next() function so why is it working fine in this case but now when we call the next() function manually?
@Sherafati it's because for loop does not call function on every iteration. It call your function once and then uses generator to get new values.
Python then makes a temporary variable and uses the same generator for every iteration. I don't exactly know how Python handles this internally, but you can work with it like the generator can be used as a list.
@Sherafati you could also do this for example: list(count_up_tp(10))
So when we use the for loop it calls the function only once and assigns it to a variable(that is of a "generator" type) and keeps calling the next() function on that variable. correct?
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.