理解python中的递归:: confused

时间:2017-07-11 12:07:26

标签: python

我想了解递归。

我有这个代码计算范围到2个数字之和。

def sum(lower, upper):
    if lower > upper:
       return 0
    else:
        return lower + sum(lower +1, upper)

print(sum(11, 30))

我试图了解存储每个递归调用的值的位置。 因此,如果下限是12而上限是30那么这个42存储在哪里?

由于 杰森

4 个答案:

答案 0 :(得分:0)

每个递归的值都存储在调用堆栈中:

您可以像这样显示函数的反汇编:

def my_sum(lower, upper):
    if lower > upper:
        return 0
    else:
        return lower + my_sum(lower +1, upper)

import dis
dis.dis(my_sum)

你得到:

  2           0 LOAD_FAST                0 (lower)
              2 LOAD_FAST                1 (upper)
              4 COMPARE_OP               4 (>)
              6 POP_JUMP_IF_FALSE       12

  3           8 LOAD_CONST               1 (0)
             10 RETURN_VALUE

  5     >>   12 LOAD_FAST                0 (lower)
             14 LOAD_GLOBAL              0 (my_sum)
             16 LOAD_FAST                0 (lower)
             18 LOAD_CONST               2 (1)
             20 BINARY_ADD
             22 LOAD_FAST                1 (upper)
             24 CALL_FUNCTION            2
             26 BINARY_ADD
             28 RETURN_VALUE
             30 LOAD_CONST               0 (None)
             32 RETURN_VALUE

LOAD_FAST例程从函数堆栈加载值。

这与临时值相同。

答案 1 :(得分:0)

Python和大多数其他语言使用称为堆栈的结构进行函数调用。如果您不熟悉stack data structure,我建议您阅读。它将使您充分了解堆栈的工作方式。

我建议您查看this tutorial for a detailed explanation

答案 2 :(得分:0)

您的代码使用不同的命名约定编写...

def compute(low, high):
    if low > high:
        return 0
    else:
        return low + compute(low+1, high)

给定一个整数(低)和另一个高于所述整数(高)的整数,此代码将通过递归找到这两个整数(包括)之间的总和。

e.g。 >>> compute(6, 9)

上面将返回30,通过递归,即每次初始条件不满足if low > high:时,再次调用该函数,将1加到low,以便最终满足条件,并且它是(当低于10时)将设置递归。

仍然使用示例compute(6, 9) - 当low = 10时,返回0,之前的低值为9,因此此时表达式return low + compute(low+1, high)将为return 9 + 0,现在为下一次递归调用,9之前的低点是8 - 我们刚从前一次调用返回9,所以return 8 + 9,返回17 ......我认为你明白了,这个过程发生在初始return语句之前。把它想象成松散的,然后让它回到它的初始形态。

请注意,如果没有最终满足的第一个条件,并且增量返回语句,该函数将无限地返回相同的内容,以便永远不会满足if条件,或者无限地将1添加到低。

我希望这会对递归有所启发。

答案 3 :(得分:0)

把它想象成一个呼叫中心。一个宣称他们告诉你你可以要求的范围内的数字总和。

所以你给那里的某个人打电话,询问12到30之间的数字总和。那个人认为"认为这对我来说太复杂了#34;并呼叫同一个呼叫中心本身,要求从13到30之间的总和。第二个人仍然无法直接执行此操作并再次呼叫中心 以要求从14到30的总和。 等等。最终有人会接到一个电话,询问31到30之间的金额并直接回复“嗯”,这是一个空的范围,当然是零#34;。然后一切都倒退了。所有参与呼叫堆栈的人,他们一直在等待他们的答案,现在逐个计算他们自己的结果并将其报告给打电话给他们的人。所以答复是" 30" (因为30 + 0),然后" 59" (因为29 + 30),然后" 87" (因为28 + 59),等等。最终,打电话并要求12到30的人将收到13到30之和为387的答案。他们将其添加到12并回复你" 399"

在这个类比中,有些人会在他们等待自己的答案时将他们的请求数据保留在他们的头脑中。在计算机编程中完成所有这些数据存储在哪里?好吧,call stack。它被称为堆栈,因为就像一堆文件一次一个地构建一个并且一次取下一个,这些调用是在彼此之上进行的,并且以相反的顺序完成。就像那个呼叫中心一样,计算机的呼叫堆栈尺寸有限。当您询问的范围大于呼叫中心的人数时,呼叫中心的每个人最终都会参与您的请求,而最后一个呼叫的人将无法与之通话。在这一点上,系统有点崩溃。在计算机中,这称为#"堆栈溢出"。就像这个网站一样。