Doubt on generators behavior

K

Krishnan Shankar

Hi Friends,

I am new to Generators and was learning the same by experimenting. I wrote
a small code which is as below.
.... print "The number is", var
.... if var % 2 == 0:
.... yield var
.... else:
.... print "Number is odd"
....
But when i was executing i saw a behavior i could not understand. When i
gave an even number,
1. The generator object was created
2. When i gave next the argument was yielded.
3. In the subsequent next the Stop Iteration was raised.
The number is 78
78Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

But When i ran with an odd number the result of "Number is odd" is printed.
But it seems the generator runs again by itself to Stop Iteration.
The number is 77
Number is odd
Traceback (most recent call last):

How did this happen automatically? I am not able to get the execution of a
generator. Can someone please help me in understanding?
Regards,
Krishnan
 
J

Jussi Piitulainen

Krishnan said:
Hi Friends,

I am new to Generators and was learning the same by experimenting. I
wrote a small code which is as below.

... print "The number is", var
... if var % 2 == 0:
... yield var
... else:
... print "Number is odd"
...

But when i was executing i saw a behavior i could not
understand. When i gave an even number,
1. The generator object was created
2. When i gave next the argument was yielded.
3. In the subsequent next the Stop Iteration was raised.

The number is 78
78
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

Yes. The yield suspended the computation at a point where all that
remains is to fall through. That happens at next, and the exception is
raised then.
But When i ran with an odd number the result of "Number is odd" is
printed. But it seems the generator runs again by itself to Stop
Iteration.

It doesn't run again. It just does what remains after the print
statement: it falls through, and the exception is raised.
The number is 77
Number is odd
Traceback (most recent call last):


How did this happen automatically? I am not able to get the
execution of a generator. Can someone please help me in
understanding?

I think you might benefit from the following experiments (untested):

def gen3(seed):
yield(seed)
yield(seed + 1)
yield(seed + 2)

def genby2(seed):
while True:
yield seed
seed += 2

def geneven(seed):
if seed % 2 == 1:
raise Exception('odd seed')
while True:
yield seed
seed += 2

def genrange(begin, end):
for k in range(begin, end):
yield k

....

Insert print statements at will, watch the behaviour, and I think
you'll get it quickly.
 
S

Steven D'Aprano

Hi Friends,

I am new to Generators and was learning the same by experimenting. I
wrote a small code which is as below.

... print "The number is", var
... if var % 2 == 0:
... yield var
... else:
... print "Number is odd"
...
But when i was executing i saw a behavior i could not understand. When i
gave an even number,
1. The generator object was created
2. When i gave next the argument was yielded. 3. In the subsequent next
the Stop Iteration was raised.

Correct. Follow the program logic. The first time you call next,
execution of the generator begins:

- the generator first prints "The number is 78";

- the "if" block is then checked, since 78 is an even number the
line "yield var" is executed and 78 is yielded;

- after "yield", execution halts until you call next again;

- when you call next the second time, execution continues following
the if...else block, which reaches the end of the function and
StopIteration is raised.

But When i ran with an odd number the result of "Number is odd" is
printed. But it seems the generator runs again by itself to Stop
Iteration.

Again, follow the program logic. The first time you call next, execution
of the generator begins:

- the generator first prints "The number is 77";

- the "if" block is then checked, since 77 is an odd number the
"else" clause is executed, and "The number is off" is printed;

- execution continues following the if...else block, which reaches
the end of the function and StopIteration is raised.


Execution only halts at a yield statement. Try experimenting with this
one:

def example():
var = 3
print "Starting with", var
yield var # pauses after this
print "execution continues..."
var -= 1
print "var now has result", var
yield var # pauses after this
var -= 1
print "var now has result", var
yield 1000 + var # pauses after this
yield "nearly done" # pauses after this
print "Finished now."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top