-2

I've written a python function to reverse a list, here are the two functions and their respective outputs.

Function 1

a=[1,5]
def rev(k,i):
    
    if i==len(k)-1:
        print("in base case {}".format(i))
        print(a[i])
        print("Return from base case")
    else:
        print("in else before recur call  {}".format(i))
        *return* rev(k,i+1)
        print("in else after recur call  {}".format(i))
        print(a[i])
rev(a,0)

Output (Function 1)

in else before recur call  0
in base case 1
5
Return from base case

Function 2

a=[1,5]
def rev(k,i):
    
    if i==len(k)-1:
        print("in base case {}".format(i))
        print(a[i])
        print("Return from base case")
    else:
        print("in else before recur call  {}".format(i))
        rev(k,i+1)
        print("in else after recur call  {}".format(i))
        print(a[i])
rev(a,0)

Outupt (Function 2)

in else before recur call  0
in base case 1
5
Return from base case
in else after recur call  0
1

In the "Function 2", when I remove return from else call and directly call the recursion function, it worked. But,why didnt it worked in first code?

In Sum of list using recursion, when we recurse we use return, so why we not using return here.

def getSum(piece):
    if len(piece)==0:
        return 0
    else:
        return piece[0] + getSum(piece[1:]) 
print getSum([1, 3, 4, 2, 5])
Linux
  • 150
  • 8

1 Answers1

2

Function calls and return works the same way for every function. Python (and most other programming languages) do not give any special treatment to any function.

A function will follow the path from first line and so on until it either is no more lines and you can think of it as a return None or it hits a return and it will return whatever the argument is back the the callee. The second example doesn't return so it continues until all the functions lines are executed. The first has 2 lines of dead code after the return that will never ever be executed and are there just to confuse readers.

print("in else before recur call {}".format(i)) does the same. It will enter the print function and you don't really know if print is recursive or not and it really doesn't matter. The only thing that matters is that once it has done its thing it returns and you continue on the next line.

Often you see people doing sillly mistakes like thinking that only the base case, which stops the recursion, needs to return its value, like in this bad code:

def has_odd(arr):
  if not arr:
     return False
  elif arr[0] % 2 == 1:
     return True
  else: 
     has_odd(arr[1:]) # The result is not returned
     

has_odd([])     # => False
has_odd([3])    # => True
has_odd([2, 3]) # => None

So whats happening in the last example. Well it recurses and returns True back to the first has_odd which does not do anything with the result and it hits the invisible return None in the end of the function. The return only works one level! since it doesn't really matter that it calls itself or anything else. Correct version is with a return:

def has_odd(arr):
  if not arr:
     return False
  elif arr[0] % 2 == 1:
     return True
  else: 
     return has_odd(arr[1:]) # return the result from the recursion
     

has_odd([])     # => False
has_odd([3])    # => True
has_odd([2, 3]) # => True

As with this example your getSum you will get errors since instead of results you get None if you try removing the return form one of the paths and then + will complain that None is not a number that can be added.

Sylwester
  • 47,942
  • 4
  • 47
  • 79