generator functions: why won't this work?

zillow10 at googlemail.com zillow10 at googlemail.com
Wed Apr 2 20:42:54 CEST 2008


On Apr 2, 3:57 pm, Mel <mwil... at the-wire.com> wrote:
> zillo... at googlemail.com wrote:
>
> I'd just like to test my
>
> > understanding of this. Suppose I create the following generator
> > object:
>
> > g = getNextScalar(1, 2, (3, 4), 5)
>
> > when the iterator reaches the tuple argument (3, 4) then, according to
> > Steve and George, the * in *arg causes this tuple to be expanded into
> > positional arguments, and it makes sense to do it this way. But what
> > happens when getNextScalar(arg) is used instead?
>
> Try it:
>
> Python 2.5.1 (r251:54863, Mar  7 2008, 04:10:12)
> [GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> def a (arg):
> ...   print arg
> ...
>  >>> def astar (*arg):
> ...   print arg
> ...
>  >>> a(3,4)
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: a() takes exactly 1 argument (2 given)
>  >>> astar(3,4)
> (3, 4)
>  >>> a((3,4))
> (3, 4)
>  >>> astar((3,4))
> ((3, 4),)
>  >>>
>
>         Mel.

Well, I understand that (unless I missed the point you're trying to
make). But with respect to the example I quoted:

def getNextScalar(*args):
        for arg in args:
                if(isinstance(arg, tuple)):
                        for f in getNextScalar(arg): # should use *arg
                                yield f
                else:
                        yield arg
 where the function is declared as def getNextScalar(*arg), but is
called using getNextScalar(arg), with arg being a tuple: here the
generator is being passed a single argument, so there's no TypeError
as in your example. However, it fails - as I understand it - because
the function keeps passing the same tuple (being unable to access the
elements inside it) and goes into an infinite loop:
>>> # works for this example, but not very useful:
>>> g = getNextScalar(1, 2, 3, 4)
>>> for i in g:
	print i


1
2
3
4

# third argument is a tuple:
>>> g = getNextScalar(1, 2, (3, 4))
>>> for i in g:
	print i


1
2

Traceback (most recent call last):
  File "<pyshell#108>", line 1, in <module>
    for i in g:
  File "<pyshell#94>", line 4, in getNextScalar
    for f in getNextScalar(arg):
  File "<pyshell#94>", line 4, in getNextScalar
    for f in getNextScalar(arg):
  File "<pyshell#94>", line 4, in getNextScalar
    for f in getNextScalar(arg):
...

AK




More information about the Python-list mailing list