Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generators and for loops in Python

Tags:

So I have a generator function, that looks like this.

def generator():     while True:         for x in range(3):             for j in range(5):                 yield x 

After I load up this function and call "next" a bunch of times, I'd expect it to yield values

0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 0 0 0 0 0 ...

But instead it just yields 0 all the time. Why is that?

>>> execfile("test.py") >>> generator <function generator at 0x10b6121b8> >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 
like image 551
Jessica Avatar asked Apr 10 '15 20:04

Jessica


People also ask

What are generators 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).

How do I iterate a generator in Python?

You need to call next() or loop through the generator object to access the values produced by the generator expression. When there isn't the next value in the generator object, a StopIteration exception is thrown. A for loop can be used to iterate the generator object.

What is difference between generator and function in Python?

Generator Functions are memory efficient, as they save a lot of memory while using generators. A normal function will return a sequence of items, but before giving the result, it creates a sequence in memory and then gives us the result, whereas the generator function produces one output at a time.

Is generator faster than for loop Python?

This generator uses an iterator, because the "for" loop is implemented using an iterator. If you time these, the generator is consistently faster. Why is this, when the generator uses an iterator? Thanks.


2 Answers

generator() initializes new generator object:

In [4]: generator() is generator() # Creating 2 separate objects Out[4]: False 

Then generator().next() gets the first value from the newly created generator object (0 in your case).

You should call generator once:

In [5]: gen = generator() # Storing new generator object, will reuse it  In [6]: [gen.next() for _ in range(6)] # Get first 6 values for demonstration purposes Out[6]: [0, 0, 0, 0, 0, 1] 

Note: generator.next was removed from Python 3 (PEP 3114) - use the next function instead:

In [7]: next(gen) Out[7]: 1 
like image 119
vaultah Avatar answered Oct 26 '22 18:10

vaultah


With each call of generator you are creating a new generator object:

generator().next() # 1st item in 1st generator  generator().next() # 1st item in 2nd generator 

Create one generator, and then call the next for subsequent items:

g = generator()  g.next() # 1st item in 1st generator g.next() # 2nd item in 1st generator 
like image 45
Malik Brahimi Avatar answered Oct 26 '22 17:10

Malik Brahimi