Why this function shows the list before returning but returns None

Asked

Viewed 673 times

3

I’m writing a function that capitalizes all the string elements of a list recursively, but it returns "strangely" None, but before returning correctly shows the capitalized list:

def cap_str_elems_r(ls=[], new_list=[]):
    if len(ls)>0:
        if isinstance(ls[0], str):
            new_list.append(ls[0].capitalize())
        else:
            new_list.append(ls[0])
    else:
        print(new_list)
        return new_list
    cap_str_elems_r(ls[1:], new_list)
#
ls=["hip", 14, "to", "hop", 12]
new_list = cap_str_elems_r(ls)
print(new_list) # amostra None
  • It’s because when you don’t else it returns nothing. Change the last line to return cap_str_elems_r(ls[1:], new_list)

  • Yes, but what is returned is the return value of the first call (not the last). P.S. I will explain better in a reply.

1 answer

3


When a function - recursive or not - is called, what matters to the calling function is its return value. Not of the functions it calls. For example:

def fatorial(n):
    if n == 1:
        return 1
    return n * fatorial(n-1)

In this case, the last recursive call will return a value, but this value will only be used by previous call to her. You need to pass this value (possibly modified, as in the example above) to the function "above" it, until you reach the calling function.

Another way to write the function fatorial above is using a accumulator - which prevents new operations from being made after the recursive call, thus consisting of a tail recursion:

def fatorial(n, acc=1): # Acumula o valor 1 inicialmente
    if n == 1:
        return acc # Retorna o valor acumulado, não 1
    return fatorial(n-1, acc * n) # Acumula o valor n no produtório

That was the same strategy you used, in the case accumulating new_list. But note that, even being tail, it is necessary to use the return at the end, to call n have access to n-1, to n-1 have access to n-2, etc, until the calling function has access to the original function.

If you do not return anything, in Python this means that the return value will be None. Then modify your last line to:

return cap_str_elems_r(ls[1:], new_list)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.