简体   繁体   中英

Yield statement blocks recursive function?

I've spent a lot of time on this issue without finding any hint... I don't understand why yield forbid my recursive function to execute, without any outputs at all.

def unlist(l):
    if isinstance(l, unicode) or isinstance(l, str):
        print "This should be printed at least !"
        yield l
    if isinstance(l, list):
        for elem in l:
            unlist(elem)

l = ['a', u'b', 1]

for each in unlist(l): print each

Any hint on where/what to look for?

You need to 'return', or in this case yield the results of the recursive call:

def unlist(l):
    if isinstance(l, unicode) or isinstance(l, str):
        print "This should be printed at least !"
        yield l
    if isinstance(l, list):
        for elem in l:
            for res in unlist(elem):
                yield res

The yield may not be strictly necessary in this case, but you need to at least loop over a generator to execute the contained code. You simply called unlist(elem) which creates the generator, but only looping over the generator causes it to execute the generator function to produce items.

Demo:

>>> def unlist(l):
...     if isinstance(l, unicode) or isinstance(l, str):
...         print "This should be printed at least !"
...         yield l
...     if isinstance(l, list):
...         for elem in l:
...             for res in unlist(elem):
...                 yield res
... 
>>> l = ['a', u'b', 1]
>>> for each in unlist(l): print each
... 
This should be printed at least !
a
This should be printed at least !
b

In Python 3.3 and newer, you can use the yield from syntax:

def unlist(l):
    if isinstance(l, unicode) or isinstance(l, str):
        print "This should be printed at least !"
        yield l
    if isinstance(l, list):
        for elem in l:
            yield from unlist(elem)

Last, but not least, you can use basestring to test for both str and unicode :

if isinstance(l, basestring):
    # either a str or a unicode value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM