Why doesn't StopIteration get caught in the following code?

Discussion in 'Python' started by grocery_stocker, Apr 4, 2009.

  1. Given the following

    [cdalten@localhost ~]$ python
    Python 2.4.3 (#1, Oct 1 2006, 18:00:19)
    [GCC 4.1.1 20060928 (Red Hat 4.1.1-28)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def counter():

    .... mylist = range(3)
    .... for i in mylist:
    .... yield i*i
    ....
    >>> counter

    <function counter at 0xb7e79e64>
    >>> gen = counter()
    >>> gen

    <generator object at 0xb7e7c1cc>
    >>> while True:

    .... i = gen.next()
    .... print i
    ....
    0
    1
    4
    Traceback (most recent call last):
    File "<stdin>", line 2, in ?
    StopIteration


    I thought the 'for' in counter() was supposed to catch StopIteration.
    Ie, I thought that something like

    .... for i in mylist:
    .... yield i*i

    Got translated to something like
    >>> try:

    .... while True:
    .... do some stuff
    .... except StopIteration:
    .... pass
    ....
     
    grocery_stocker, Apr 4, 2009
    #1
    1. Advertising

  2. grocery_stocker

    Dave Angel Guest

    grocery_stocker wrote:
    > Given the following
    >
    > [cdalten@localhost ~]$ python
    > Python 2.4.3 (#1, Oct 1 2006, 18:00:19)
    > [GCC 4.1.1 20060928 (Red Hat 4.1.1-28)] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.
    >
    >>>> def counter():
    >>>>

    > ... mylist = range(3)
    > ... for i in mylist:
    > ... yield i*i
    > ...
    >
    >>>> counter
    >>>>

    > <function counter at 0xb7e79e64>
    >
    >>>> gen = counter()
    >>>> gen
    >>>>

    > <generator object at 0xb7e7c1cc>
    >
    >>>> while True:
    >>>>

    > ... i = gen.next()
    > ... print i
    > ...
    > 0
    > 1
    > 4
    > Traceback (most recent call last):
    > File "<stdin>", line 2, in ?
    > StopIteration
    >
    >
    > I thought the 'for' in counter() was supposed to catch StopIteration.
    > Ie, I thought that something like
    >
    > ... for i in mylist:
    > ... yield i*i
    >
    > Got translated to something like
    >
    >>>> try:
    >>>>

    > ... while True:
    > ... do some stuff
    > ... except StopIteration:
    > ... pass
    > ...
    >
    >
    >

    There are two separate StopIteration's here. The for statement you
    describe will indeed catch the StopIteration from the list's iterator.

    But that for statement is inside a generator function, and the generator
    function throws a StopIteration when it returns (as opposed to when it
    yields). If you had used that generator inside another for statement,
    it would have worked as you expect. But when you call nest()
    explicitly, you have to be prepared for the exception. Clearly, the
    while True loop cannot go forever, when your generator is finite.
     
    Dave Angel, Apr 4, 2009
    #2
    1. Advertising

  3. grocery_stocker

    Terry Reedy Guest

    grocery_stocker wrote:
    ....
    >>>> while True:

    > ... i = gen.next()
    > ... print i
    > ...
    > 0
    > 1
    > 4
    > Traceback (most recent call last):
    > File "<stdin>", line 2, in ?
    > StopIteration


    If you had written

    for item in gen: print(i)

    then StopIteration from gen would be caught.

    One expansion of a for loop is (in the above case)

    it = iter(gen) # not needed here, but is for general iterables
    try:
    while True:
    i = it.next()
    print(i) # or whatever the loop body is
    except StopIteration:
    pass

    In other words, 'for i in iterable' expands to several lines of
    boilerplate code. It is very useful syntactic sugar.

    You left out the try..except part.
     
    Terry Reedy, Apr 5, 2009
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter Otten
    Replies:
    16
    Views:
    750
    Raymond Hettinger
    Apr 5, 2005
  2. Using StopIteration

    , May 8, 2006, in forum: Python
    Replies:
    5
    Views:
    482
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,970
    Smokey Grindel
    Dec 2, 2006
  4. Chris
    Replies:
    7
    Views:
    410
    Chris
    Jan 25, 2007
  5. Kris Kowal
    Replies:
    5
    Views:
    334
Loading...

Share This Page