2016-09-09 145 views
0

我想了解当这个递归函数被调用时会发生什么。该代码应该是一个跟踪了解递归函数python

def mysum(lower, upper, margin): 
    blanks = ' ' * margin 
    print blanks, lower, upper 
    if lower > upper: 
     print blanks, 0 
     return 0 
    else: 
     result = lower + mysum(lower + 1, upper, margin + 4) 
     print blanks, result, lower, margin 
     return result 

if __name__ == "__main__": 
    mysum(1, 4, 0) 

输出读取

1 4 
    2 4 
     3 4 
      4 4 
       5 4 
       0 
      4 4 12 
     7 3 8 
    9 2 4 
10 1 0 

我不明白为什么功能开始开卷后返回0,你能不能帮我跟进会发生什么

回答

0

下面是带有注释的代码,帮助您了解递归函数的工作原理。

def mysum(lower, upper, margin): 
    blanks = ' ' * margin  # First time : margin = 0 
           # 2nd time : margin = 4 
    print blanks, lower, upper # first time : lower = 1, upper = 4 
           # 2nd time : lower = 2, upper = 4 
    if lower > upper: # first time : go to else (& 2nd time, ... until lower =5) 
     print blanks, 0 
     return 0 
    else: 
     result = lower + mysum(lower + 1, upper, margin + 4) # result is not directly calulated 
                   # first it need to execute the call to 
                   # the function, it will be the second call 
     print blanks, result, lower, margin 
     return result 

if __name__ == "__main__": 
    mysum(1, 4, 0)  # First call of your function 

当下是5,没有调用mysum并返回0 所以您放松身心,只需一个步骤:下层是4,和你在哪里,在“其他”的一部分。你必须完成它

result = lower + mysum(lower + 1, upper, margin + 4) 
print blanks, result, lower, margin 
return result 

低= 4,最后调用返回0结果= 4 你放松又迈进了一步:下层是在3,呼叫刚刚返回一个4之前,所以新的结果是7.返回此值。

现在,低= 3,你做的一样,较低= 2,低= 1

可以看到,1 + 2 + 3 + 4 = 10,它是你的函数的结果。 我希望我帮助你,告诉我如果你不明白,也许我可以找到另一种解释方式...:/

0

简而言之,在达到return声明之前,您总是先进行递归调用,直至达到基本情况。然后,在到达另一个递归调用之前,您总是会遇到return声明(因为只有一个递归调用,所以这样做很简单)。

0

当函数的一个调用返回0(“bottom_sout”)时,可能会有许多其他调用到堆栈上的函数,等待继续。当递归降到最低时,控制权返回栈上的最后一个函数。它完成其工作并返回,并控制返回到堆栈上的下一个早期函数。这种情况一直持续到mysum的所有调用都已从堆栈中移除,与其放入堆栈的顺序相反。

也许你已经理解了所有的东西:)如果是这样,请澄清你的意思是“为什么功能开始放松”。

+0

我最初认为,在函数达到基本情况后,它会终止,我没有意识到它有一些其他调用留在调用堆栈 – diogenes

0

我认为这里有用的观察是前五行是在任何嵌套调用返回之前打印的。这一切都发生在函数体的第一部分:

print - 检查条件 - 转到else - 再次开始,更深一层。

当打印0时,最深的通话返回,所以计算第二深度result。然后发生下一行的print - 它是第一行,其中包含3个数字。然后你再次击中return,所以计算出另一个result等等。连续的回报对应于较早的呼叫 - 因此它们具有较少的blanks