【问题标题】:understanding recursion in a function which uses generator理解使用生成器的函数中的递归
【发布时间】:2013-06-07 12:01:12
【问题描述】:

这是一个函数

def flatten(nested):
   try:
        for sublist in nested:
            for element in flatten(sublist):
                yield element
   except TypeError:
       yield nested

nested=[[1, 2], [3, 4], [5]]

我想了解的是第一次调用 flatten 函数的时间 整个序列([[1, 2], [3, 4], [5]])传递给它,下面是我理解的执行顺序

 flatten([[1, 2], [3, 4], [5]]):
   try:
        for sublist in ([[1, 2], [3, 4], [5]]):
            for element in flatten(sublist):

这里调用了 flatten,它从嵌套 [0] 的列表元素 [1,2] 开始

现在在这个递归调用中进行展平,它按照以下方式进行

 flatten([1, 2]):
   try:
        for sublist in ([1, 2]):
            for element in flatten(sublist):

但在最后一种情况下 [5] 发生了什么

  for sublist in ([5]):
                for element in flatten(sublist):

现在在递归调用中,flatten 是如何工作的?我也不清楚是否, 输入不是一个定义明确的列表输入在列表之后[[[1],2],3,4,[5,[6,7]],8]

那么递归调用是怎么发生的,这个东西我不是很清楚。

【问题讨论】:

  • 你可以看到 try...except 块为 if(type(nested) == list ) ...else #type(nested) == integer

标签: python python-2.7 recursion generator


【解决方案1】:

在第 4 行,再次调用 flatten。 当到达一个元素时,会触发类型错误,并产生它。

否则会再次调用 flatten。

【讨论】:

  • 是的,因为“for sublist in (5):”会抛出错误,5 是一个值而不是一个可迭代的列表(示例)
【解决方案2】:
def flatten(nested, depth=0):
    print "-> %d : %s" % (depth, nested)
    try:
        for sublist in nested:
            print " s %d : %s" % (depth, sublist)
            for element in flatten(sublist, depth+1):
                print " e %d : %s" % (depth, element)
                yield element
    except TypeError:
        print " y %d : %s" % (depth, nested)
        yield nested

您可以准确地追踪它是如何与上述内容一起工作的......

【讨论】:

    【解决方案3】:

    我不是 python 人,但在我看来这个 faltten 是这样工作的:

    1. 它会递归地尝试为每个元素调用自己,直到发生 TypeError

    2. 当发生 TypeError 时,这意味着该元素不是集合,无法进一步展平,因此将生成该元素。

    示例:flatten [[[1],2],3,4,[5,[6,7]],8]

    1st call 1st step: sublist = [[1],2]
    2nd call 1st step: sublist = [1]
    3nd call 1st step: type error | yield : [1]
    2nd call 2nd step: type error | yield : [1,2]
    1st call 2nd step: type error | yield : [1,2,3]
    

    .... 等等。

    【讨论】:

      【解决方案4】:

      您始终可以添加日志记录以了解何时执行某些方法以及使用哪些参数:

      def flatten(nested):
          print(nested)
          try:
              for sublist in nested:
                  for element in flatten(sublist):
                      yield element
          except TypeError:
              yield nested
      

      调用顺序会是这样的:

      [[[1], 2], 3, 4, [5, [6, 7]], 8]
      [[1], 2]
      [1]
      1
      2
      3
      4
      [5, [6, 7]]
      5
      [6, 7]
      6
      7
      8
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-25
        • 2016-04-03
        • 1970-01-01
        • 2018-09-08
        • 1970-01-01
        • 2015-01-27
        • 1970-01-01
        • 2012-04-06
        相关资源
        最近更新 更多