generator with subfunction calling yield

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • andy.leszczynski@gmail.com

    #1

    generator with subfunction calling yield

    Hi,

    I might understand why this does not work, but I am not convinced it
    should not - following:

    def nnn():
    print 'inside'
    yield 1

    def nn():
    def _nn():
    print 'inside'
    yield 1

    print 'before'
    _nn()
    print 'after'


    for i in nnn():
    print i

    for i in nn():
    print i



    gives results:

    $ python f.py
    inside
    1
    before
    after
    Traceback (most recent call last):
    File "f.py", line 18, in ?
    for i in nn():
    TypeError: iteration over non-sequence

    while I would expect:
    $ python f.py
    inside
    1
    before
    inside
    1
    after

    Any insight?

    andy

  • James Stroud

    #2
    Re: generator with subfunction calling yield

    andy.leszczynsk i@gmail.com wrote:
    Hi,
    >
    I might understand why this does not work, but I am not convinced it
    should not - following:
    >
    def nnn():
    print 'inside'
    yield 1
    >
    def nn():
    def _nn():
    print 'inside'
    yield 1
    >
    print 'before'
    _nn()
    print 'after'
    >
    >
    for i in nnn():
    print i
    >
    for i in nn():
    print i
    >
    >
    >
    gives results:
    >
    $ python f.py
    inside
    1
    before
    after
    Traceback (most recent call last):
    File "f.py", line 18, in ?
    for i in nn():
    TypeError: iteration over non-sequence
    >
    while I would expect:
    $ python f.py
    inside
    1
    before
    inside
    1
    after
    >
    Any insight?
    >
    andy
    >
    In the commented line, you are only creating a generator. This is not
    equivalent to calling its "next" function, i.e., nothing will be
    "yielded" the way you have written it.


    def nn():
    def _nn():
    print 'inside'
    yield 1

    print 'before'
    _nn() # <== just makes a generator
    print 'after'

    James

    --
    James Stroud
    UCLA-DOE Institute for Genomics and Proteomics
    Box 951570
    Los Angeles, CA 90095


    Comment

    • Rob Williscroft

      #3
      Re: generator with subfunction calling yield

      wrote in news:1159396746 .073994.28680@h 48g2000cwc.goog legroups.com in
      comp.lang.pytho n:
      Any insight?
      From the docs:

      <quote>
      The yield statement is only used when defining a generator function, and is
      only used in the body of the generator function. Using a yield statement in
      a function definition is sufficient to cause that definition to create a
      generator function instead of a normal function.
      </quote>

      Note that its when a function defention contains a yeild statement
      (expression) that the defenition is taken to be a generator function.
      def nn():
      >
      def _nn():
      print 'inside'
      yield 1
      >
      print 'before'
      >
      _nn()
      print 'after'
      So tha above (nn()) isn't a generator as it doesn't contain a
      yield statement.

      Note also that the call to _nn() returns a generator, it isn't a
      regular function call.

      Here is nn() re-writen to return what you may have originaly expected:

      def nn():
      def _nn():
      print 'inside'
      yield 1

      print 'before'

      for i in _nn():
      yield i

      print 'after'

      So to forward another generator you need to iterate over it and
      yield each element, just as you would for any other iterable.

      Rob.
      --

      Comment

      • Matimus

        #4
        Re: generator with subfunction calling yield

        The issue is that nn() does not return an iterable object. _nn()
        returns an iterable object but nothing is done with it. Either of the
        following should work though:

        def nn():
        def _nn():
        print 'inside'
        yield 1
        print 'before'
        for i in _nn():
        yield i
        print 'after'

        Or you could just return the iterable object that was returned by
        _nn():

        def nn():
        def _nn():
        print 'inside'
        yield 1
        print 'before'
        retval = _nn():
        print 'after'
        return retval

        For clarification, using yeild creates a generator. That generator
        returns an iterable object. Nesting generators does not somehow
        magically throw the values up the stack. I made the same mistake when I
        first started messing with generators too.

        -Matt

        andy.leszczynsk i@gmail.com wrote:
        Hi,
        >
        I might understand why this does not work, but I am not convinced it
        should not - following:
        >
        def nnn():
        print 'inside'
        yield 1
        >
        def nn():
        def _nn():
        print 'inside'
        yield 1
        >
        print 'before'
        _nn()
        print 'after'
        >
        >
        for i in nnn():
        print i
        >
        for i in nn():
        print i
        >
        >
        >
        gives results:
        >
        $ python f.py
        inside
        1
        before
        after
        Traceback (most recent call last):
        File "f.py", line 18, in ?
        for i in nn():
        TypeError: iteration over non-sequence
        >
        while I would expect:
        $ python f.py
        inside
        1
        before
        inside
        1
        after
        >
        Any insight?
        >
        andy

        Comment

        Working...