I\'m a programming newbie and am having some trouble understanding an example from my python textbook (\"Beginning Python\" by Magnus Lie Hetland). The example is for a recu
yield element
can be executed if nested
is a list but sublist
is not (i.e., if nested
is a normal "flat" list). In this case, for sublist in nested
will work fine. When the next line recursively calls flatten sublist
a typerror will be raised when the recursive call tries to iterate over the "sublist" (which is not iterable). This TypeError is caught and the recursive call yields the entire input list back, so it is then iterated over by the for element in flatten(sublist)
call. In other words, for element in flatten(sublist)
winds up doing for element in sublist
if sublist is already flat.
The key thing to recognize is that even a non-nested list will result in a recursive call. A call like flatten([1])
will result in two yields: the recursive call will yield [1]
to the outer call, and the outer call immediately re-yields 1
.
This version of the function may help to understand what's going on:
def flatten(nested, indent=""):
try:
print indent, "Going to iterate over", nested
for sublist in nested:
print indent, "Going to iterate over flattening of", sublist
for element in flatten(sublist, indent+" "):
print indent, "Yielding", element
yield element
except TypeError:
print indent, "Type Error! Yielding", nested
yield nested
>>> list(flatten([[1,2],3]))
Going to iterate over [[1, 2], 3]
Going to iterate over flattening of [1, 2]
Going to iterate over [1, 2]
Going to iterate over flattening of 1
Going to iterate over 1
Type Error! Yielding 1
Yielding 1
Yielding 1
Going to iterate over flattening of 2
Going to iterate over 2
Type Error! Yielding 2
Yielding 2
Yielding 2
Going to iterate over flattening of 3
Going to iterate over 3
Type Error! Yielding 3
Yielding 3
[1, 2, 3]