Why this function shows the list before returning but returns None

3

I'm writing a function that capitalizes all the string elements of a list recursively, but it returns "strangely" None, but before returning it correctly lists 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
    
asked by anonymous 09.11.2014 / 21:55

1 answer

4

When a function - recursive or not - is called, what matters to the calling function is the return value of it. Not the functions she 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 the previous call to it . You need to pass this value (possibly modified, as in the example above) to the "above" function, until you get to the calling function.

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

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

This was the same strategy you used, in this case amassing new_list . But note that, even though it is a tail, it is necessary to use return at the end, for call n access n-1 , n-1 access 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)
    
09.11.2014 / 22:18