关于python递归函数的混淆

时间:2016-09-26 05:41:53

标签: python recursion

我在线获得了print_backward功能代码,但我很困惑 关于它如何工作和它的输出。

以下是我的代码。

def print_backward(num):
    if num == 10:
        return 
    num += 1
    print(num)
    print_backward(num)
    print("yeah")   
    print(num)
    print()

print_backward(6)

以下是输出。

7
8
9
10
yeah
10

yeah
9

yeah
8

yeah
7

我可以理解它每次打电话时的打印方式是7到10 递归地,num + = 1。

但我很困惑,一旦数量达到10,print_backward就应该 返回,然后完成。它不应该打印是的10,是的9,是的8,是的 7.为什么这段代码调用了return,它仍然可以打印?这段代码如何向后打印,这就是为什么我调用它print(num)的原因 可以打印10到7?

5 个答案:

答案 0 :(得分:1)

函数调用实际上是一个堆栈操作。递归是函数调用的一个特例。

每次调用函数时,返回地址都将被推入堆栈,当函数返回时,程序将从堆栈顶部弹出返回地址,程序继续从那里执行。您可以查看wikipedia中有关call stack的官方说明。

对于您的示例,print_backward(7)先调用,然后下一个命令将进入堆栈,然后当您调用print_backward(8)时,下一个命令将再次被推入堆栈,因此在4次递归调用之后,堆栈将是这样的:

+-------------------------+ <--- Stack top
| num = 10, print("yeah") | \
| num = 9,  print("yeah") |  |
| num = 8,  print("yeah") |   >   Call stack
| num = 7,  print("yeah") |  |
+-------------------------+ /

num == 10:致电时,条件符合if条件print_backward(10)。程序执行return语句,堆栈顶部的Return address将弹出,程序从那里开始,这意味着,{= 1}}将执行num = 10。完成对print('yeah')的调用后,堆栈将从堆栈中弹出另一个返回地址,print_backward(10)中的print('yeah')将被执行。当堆栈为空时,此操作将结束,这意味着没有更多的函数返回。

答案 1 :(得分:0)

在第一次运行时,代码不会超过print_backward(num)的内部调用,即4次(如无限递归)

当参数达到10时,所有函数都会返回并进一步打印原始的num + 1,并调用它们。

首先打印最高的数字,因为数字较高的呼叫首先返回。

答案 2 :(得分:0)

函数调用通过堆栈发生。

你在6上调用print_backward。所以堆栈将有6.
现在你打电话给7 ---&gt;堆栈有6,7,其中7是顶部。
现在你打电话给8 ----&gt;堆栈是6,7,8
现在9,所以堆栈是6,7,8,9
现在10,所以堆栈是6,7,8,9,10。

现在当函数返回时,它会从堆栈中弹出。
所以,你在参数10的函数中。所以,你调用了return,它从堆栈中弹出。现在堆栈是6,7,8,9。
现在它打印“是”和10(因为num是9,我们之前做了num = num + 1)。 现在它返回并弹出9.现在堆栈是6,7,8
现在它打印是啊和9因为num是8而我们之前做过num = num +1。

同样,它也打印其他。

答案 3 :(得分:0)

对于你的情况 - print_backward(6)它需要4次调用(递归地)才能达到返回条件,即if num == 10 - 在这些调用期间打印函数:

7  # print_backward(6) - first call we made
8  # print_backward(7) - recursive
9  # print_backward(8) - recursive
10 # print_backward(9) - recursive - inner most, where the return is executed 

对于下一个递归调用print_backward(10),返回条件变为true,函数开始返回(从最内部调用开始) - 结果是递归调用(第6行)下面的行被调用,即

yeah # 4th call (inner most) returned
10

yeah # 3rd call returned
9

yeah # 2nd call returned
8

yeah # 1st call returned
7

调用堆栈视图可视化&#d>:

print_backward(6)
| 7 # num += 1 and then print(num)
| print_backward(7)
| | 8
| | print_backward(8)
| | | 9
| | | print_backward(9)
| | | | 10
| | | | | print_backward(10)
| | | | | | return 
| | | | yeah # print("yeah")   
| | | | 10   # print(num)
| | | | ()   # print()
| | | yeah
| | | 9
| | | ()
| | yeah
| | 8
| | ()
| yeah
| 7
| ()

答案 4 :(得分:0)

当调用print_backward(6)时

1 check for 10
2 increase 6 by one num = 7
3 print 7
4 call backward with 7

for 6 print_backward尚未完成,print_backward(7)被推到堆栈顶部。其余部分

print("yeah")
print(7)
递归调用完成后,

将最后执行。我在下面的步骤中跳过支票10。将包括在最后的步骤。

5 increase 7 by one num = 8
6 print 8
7 call backward with 8 (7 not completed)
8 increase 8 by one num = 9
9 print 9
10 call backward with 9 (8 not completed)
11 increase 9 by one num = 10
12 print 10
return is encountered  
13 call backward with 10 (9 not completed)
14 check for 10 and return. 9 will continue for the execution.
15 in the execution of 9 num is 10 so yeah is printed and then 10 is printed and print_backward for 9 is completed. Similarly for 8 num is 9 which print yeah followed by 9 and so on.