递归函数完成后返回0。为什么“返回0”不覆盖该函数的先前返回值?

时间:2018-07-05 11:12:34

标签: python

该函数查找列表中各项的总和,并且工作正常。它将列表中的第一项与列表的其余部分相加。 递归调用函数 mysum ,直到它为空。 当列表为空时,它返回0。但是为什么不覆盖该函数的先前返回值?

>>> def mysum(L):
       if not L:
           return 0
       else:
           return L[0] + mysum(L[1:]) 

>>> mysum([1, 2, 3, 4, 5])
15

5 个答案:

答案 0 :(得分:2)

因为该函数的第一个调用是返回的最后一个。假设您有列表[1,2,3]。您的代码将最终以

return 1 + sum([2, 3])

其中1 + sum([2,3])表达式。在此表达式变为值之前,代码将在那里等待。因此,它使此功能保持打开状态并等待sum(2,3])的结果。本质上,您的代码变为

return 1 + (return 2 + sum([3]))

同样,2 + sum([3])需要等待sum([3]),您最终会得到类似

的信息
return 1 + (return 2 + (return 3 + sum([])))

现在,sum([])不必等待任何人,它变成了0,所以

return 1 + (return 2 + (return 3 + 0))
return 1 + (return 2 + 3)
return 1 + 5
return 6

答案 1 :(得分:0)

递归调用的结果不仅会沿调用堆栈传递(例如return mysum(L[1:])),而且还会在每个中间步骤进行处理:

def mysum(L):
    if not L:
        return 0  # -------+
    else:  #               |       
        return L[0] + mysum(L[1:]) 
        #             ^^^^^^^^^^^^ == 0  for the innermost call
        #      ^^^^^               != 0  in the general case
        #      ^^^^^^^^^^^^^^^^^^^ != 0  hence

答案 2 :(得分:0)

1. mysum([1, 2, 3, 4, 5])

L不为空,所以我们转到else:

2. return 1 + mysum([2, 3, 4, 5])

L不为空,所以我们转到else:

3. return 2 + mysum([3, 4, 5])

L不为空,所以我们转到else:

4. return 3 + mysum([4, 5])

L不为空,所以我们转到else:

5. return 4 + mysum([5])

L不为空,所以我们转到else:

6. return 5 + mysum([])

L 为空,因此我们不进行其他操作:

7. return 0

现在我们知道mysum([])的值了,让我们看看6的值是什么:

6'. return 5 + 0

这是5。现在我们知道mysum([5])的值了,让我们看看5的值是什么:

5'. return 4 + 5

这是9。现在我们知道mysum([4, 5])的值了,让我们看看4的值是:

4'. return 3 + 9

这是12。现在我们知道mysum([3, 4, 5])的值了,让我们看看3的值是:

3'. return 2 + 12

这是14。现在我们知道mysum([2, 3, 4, 5])的值了,让我们看看2的值是:

2'. return 1 + 14

现在我们知道mysum([1, 2, 3, 4, 5])的值:15。

答案 3 :(得分:0)

递归没有什么特别的。您将返回L[0]的结果以及某些函数调用的结果。图像“某些函数调用”是对其他任何函数的调用:

else:
    return L[0] + sum(L[1:])

您希望以某种方式覆盖收益吗?当然不是。在这里是mysum而不是sum没什么不同。

答案 4 :(得分:0)

递归功能的行为可以表示为调用树。并在“返回”之前完成呼叫。

因此,在您的示例中:

调用mysum([1、2、3、4、5])可以做到:

步骤1-返回1 +调用mysum([2,3,4,5])

步骤2-后面的调用返回2 +调用mysum([3,4,5])

第3步-后一个调用返回3个调用mysum([4,5])

步骤4-后面的调用返回4 +调用mysum([5])

第5步-后一个调用返回5个调用mysum([])

第6步-后一个调用返回0

第7步-进入通话树并进行添加。