Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #56764 > unrolled thread

Doubt on generators behavior

Started byKrishnan Shankar <i.am.songoku@gmail.com>
First post2013-10-13 13:49 +0530
Last post2013-10-13 09:14 +0000
Articles 3 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  Doubt on generators behavior Krishnan Shankar <i.am.songoku@gmail.com> - 2013-10-13 13:49 +0530
    Re: Doubt on generators behavior Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-10-13 11:39 +0300
    Re: Doubt on generators behavior Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-10-13 09:14 +0000

#56764 — Doubt on generators behavior

FromKrishnan Shankar <i.am.songoku@gmail.com>
Date2013-10-13 13:49 +0530
SubjectDoubt on generators behavior
Message-ID<mailman.1049.1381652399.18130.python-list@python.org>

[Multipart message — attachments visible in raw view] — view raw

Hi Friends,

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

>>> def test_gen(var):
...     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.

>>> res = test_gen(78)
>>> res.next()
The number is 78
78
>>> res.next()
Traceback (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.

>>> res2 = test_gen(77)
>>> res2.next()
The number is 77
Number is odd
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

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

[toc] | [next] | [standalone]


#56765

FromJussi Piitulainen <jpiitula@ling.helsinki.fi>
Date2013-10-13 11:39 +0300
Message-ID<qotsiw5k1in.fsf@ruuvi.it.helsinki.fi>
In reply to#56764
Krishnan Shankar writes:

> Hi Friends,
> 
> I am new to Generators and was learning the same by experimenting. I
> wrote a small code which is as below.
> 
> >>> def test_gen(var):
> ...     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.
> 
> >>> res = test_gen(78)
> >>> res.next()
> The number is 78
> 78
> >>> res.next()
> 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.

> >>> res2 = test_gen(77)
> >>> res2.next()
> The number is 77
> Number is odd
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> StopIteration
> >>>
> 
> 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.

[toc] | [prev] | [next] | [standalone]


#56766

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-10-13 09:14 +0000
Message-ID<525a646e$0$29984$c3e8da3$5496439d@news.astraweb.com>
In reply to#56764
On Sun, 13 Oct 2013 13:49:53 +0530, Krishnan Shankar wrote:

> Hi Friends,
> 
> I am new to Generators and was learning the same by experimenting. I
> wrote a small code which is as below.
> 
>>>> def test_gen(var):
> ...     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."



-- 
Steven

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web