Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using next() on generator function

I have this generator function:-

def gen():
    for i in range(3):
        yield i*i

Now when I am calling next() on gen(), it is giving the first element each time.

>>> next(gen())
0
>>> next(gen())
0

But when I use that in a for loop, it works as expected:

>>> for i in gen():
...     print(i)
... 
0
1
4

Can someone explain the cause of this effect and the concept that I am missing here?

like image 936
Vicrobot Avatar asked May 28 '18 20:05

Vicrobot


People also ask

What is next in generator in Python?

The next() function is useful when working with iterators and it's a must-know for Python developers. The Python next() function takes as first argument an iterator and as an optional argument a default value. Every time next() is called it returns the next item in the iterator until no items are left.

What is generator next?

prototype. next() The next() method returns an object with two properties done and value . You can also provide a parameter to the next method to send a value to the generator.

What does the close () method do to a generator?

close() . Raises a GeneratorExit at the point where the generator function was paused.

What are generator functions in Python?

Python generators are a simple way of creating iterators. All the work we mentioned above are automatically handled by generators in Python. Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at a time).


2 Answers

Your function returns a new generator each time you call gen().

I think the simplest way to understand is to contrast what you are doing:

>>> next(gen())
0
>>> next(gen())
0

with this:

>>> my_gen = gen()
>>> next(my_gen)
0
>>> next(my_gen)
1
>>> next(my_gen)
4
>>> next(my_gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

In this latter case, I am getting new values from the same generator.

like image 106
Samuel Dion-Girardeau Avatar answered Sep 30 '22 01:09

Samuel Dion-Girardeau


Each time you call the function it returns a generator object. And each time you call the next on it you'll get the first item which is 0 * 0 because you're not calling the next on same object (each time a new one). But in second case you're looping over one generator object and it will continue to consuming the generator until it hit the StopIteration.

For a better demonstration you can create two iterator objects from your generator function and loop over them simultaneously:

In [17]: g = gen()

In [18]: k = gen()

In [19]: for i, j in zip(g, k):
    ...:     print(i, j)
    ...:     
0 0
1 1
4 4
like image 34
Mazdak Avatar answered Sep 30 '22 00:09

Mazdak