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