Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Generator: confusing result

I'm playing around with generators to better understand how they work, but I'm confused with the result of the following piece of code:

>>> def gen():
...  for i in range(5):
...   yield i
...
>>> count=gen()
>>> for i in count:
...  print count.next()
...
1
3
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
StopIteration
>>>

What's going on here? Looks like as it hits the "for i in count:" line the generator yields the first value. I'm not sure.

EDIT: I should add that I'm not trying to "get it right". I'm trying to break things to see how Python reacts. I learn more about the language when I generate errors. This error had me stump but it's all clear now. So far all the answers have been short and sweet. Thank you every one!

like image 771
solid Avatar asked Oct 13 '15 10:10

solid


3 Answers

Because "for" cycle already iterate your generator values, at every step two values are yielded: one in "for" and one in body of cycle.

like image 41
Eugene Soldatov Avatar answered Sep 22 '22 17:09

Eugene Soldatov


Your code should be like this

Code:

def gen():
    for i in range(5):
        yield i

count=gen()
for i in count:
    print i

output:

0
1
2
3
4

Notes:

When you loop for i in count you trying to get the next item again here count.next() you trying to get the second element .So basically you are trying to get element +2 from current position

So what happens in you code is are as below:

steps :

1.for i in count here the next value is got which is0

2.print count.next() here again next value is called and printed so 1 is printed

3.for i in count here again next value is called which is 2

4.print count.next() here again next value is called and printed so 3 is printed

5.for i in count here again next value is called which is 4

6.finally here you are calling print count.next() since there is no value in the generator .You have been give the exception StopIteration

like image 130
The6thSense Avatar answered Sep 24 '22 17:09

The6thSense


for i in count: is already calling next (and assigns the value to i). Your code is then calling next again.

If you just want to print each value

for i in count:
    print i

or the long way round

while True:
    try:
        print count.next()
    except StopIteration, si:
        break
like image 37
Holloway Avatar answered Sep 22 '22 17:09

Holloway