简体   繁体   中英

understanding recursive function python

I am trying to understand what happens when this recursive function is called. The code is supposed to be a trace

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)

the output reads

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

I don't understand why the function begins to unwind after it returns 0. Can you help me follow through what happens

In brief, you always make a recursive call before you reach a return statement, until you reach the base case. Then, you always reach a return statement before you reach another recursive call (trivially so, since there is only one recursive call).

When one call of the function returns 0 ("bottoms out"), there might be many other calls to the function on the stack, waiting to proceed. When the recursion bottoms out, control returns to the last-but-one function on the stack. It finishes its work and returns, and control returns to the next earlier function on the stack. This continues until all the calls to mysum have been removed from the stack, in reverse order to the order on which they were put on the stack.

Maybe you understood all that already :) If so, please clarify what you mean by "why the function begins to unwind."

I think a useful observation here is that the first five lines are printed before any of the nested calls returns. This all happens in the first part of the function body:

print - check condition - go to else - and go to beginning again, one level deeper.

When 0 is printed, the deepest call returns, so the second-deepest result gets calculated. Then the print from the next line occurs - and it's the first line with 3 numbers in it. Then you hit another return , so another result is calculated, etc. The consecutive returns correspond to earlier calls - thus they have less blanks .

Here is the code with comments helping you to begin to understand how the recursive function works.

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

When lower is at 5, there is no call to mysum and it returns 0. So you unwind just one step : lower is at 4, and you where in the "else" part. You have to finish it

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

with lower = 4 and the last call returned 0. The result = 4. And you unwind another step : lower is at 3, and the call just before returned a 4, so the new result is 7. This value is returned.

Now, lower = 3, you do the same, for lower = 2, lower = 1.

You can see that 1 + 2 + 3 + 4 = 10. And it is the result of your function. I hope that I helped you, tell me if you don't understand, maybe can I find another way to explain ... :/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM