Recursive generator for flattening nested lists

前端 未结 5 1546
离开以前
离开以前 2020-12-03 12:04

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

5条回答
  •  醉梦人生
    2020-12-03 12:48

    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]
    

提交回复
热议问题