sintaxis recursivos recursividad recursiva programacion problemas pilas informatica funcion fractal ejemplos arbol algoritmo python recursion return

recursivos - recursividad python ejemplos



Retorno en la funciĆ³n recursiva (3)

Acabo de comenzar a aprender Python (v3.2.3) y he encontrado un problema extraño sobre el return en esta función:

def test(x): if x > 9 : test(x - 10) else: print(''real value'',x) return x x = int(input()) y = test(x) print(''this should be real value'',y)

Cuando lo ejecuto, obtengo:

45 real value 5 this should be real value None

Pero esperaba:

45 real value 5 this should be real value 5

Traté de agregar return x fuera de if y obtuve el valor de entrada predeterminado. ¿Alguien puede explicar cómo funciona el return ?


La devolución está sangrada, por lo que solo se ejecuta en la rama else. Si se toma la primera rama, la función devuelve implícitamente None.

Debes cambiar esto a

return test(x-10)


Olvidaste devolver el valor cuando x > 9 . Sin el valor de retorno, la función "devolverá" None .


Usted invoca la test(45) . Esto prueba si 45 > 9 , que es verdadero, por lo que invoca la test(35) (45 - 10), sin devolver su resultado. Lo mismo sucede con la test(25) y la test(15) , hasta que finalmente se invoca la test(5) .

Esto imprime ''valor real 5'', y luego devuelve 5. Pero devolver un resultado de una función siempre lo devuelve al llamador directo de esta función. No salta inmediatamente a través de varias llamadas; después de todo, la persona que llama puede querer hacer algo con el resultado devuelto antes de devolverle algo a la persona que llama. Sin embargo, en este caso, solo la test(5) devuelve algo; todas las demás llaman a test(x - 10) , esperan que vuelva, ignoran lo que devuelve y luego (implícitamente) devuelven None . Como la test(45) invocación más externa test(45) es uno de estos casos, lo que obtiene es None .

Aquí hay un intento de visualización de lo que sucede:

test(45): | test(35): | | test(25): | | | test(15): | | | | test(5): | | | | | print(''real value'',5) | | | | | return 5 to test(15) | | | | return None to test(25) | | | return None to test(35) | | return None to test(45) | return None

No llamó al test(5) en el intérprete, se llamó al test(5) desde otra llamada a la función. Entonces el retorno de la test(5) va a esa llamada de función . El hecho de que se trate de una función que se llama a sí misma es completamente irrelevante . Obtendrás exactamente los mismos resultados si tu código se viera así:

def test45(x): if x > 9 : test35(x - 10) else: print(''real value'',x) return x def test35(x): if x > 9 : test25(x - 10) else: print(''real value'',x) return x def test25(x): if x > 9 : test15(x - 10) else: print(''real value'',x) return x def test15(x): if x > 9 : test5(x - 10) else: print(''real value'',x) return x def test5(x): if x > 9 : print ''No more tests :('' else: print(''real value'',x) return x

La función de prueba (x) a la que llama con ''x = 45'' es lo mismo que llamar a test45(45) . Espero que puedan ver por qué es obvio que None debería devolverse cuando la recursión no está involucrada. Bueno, cuando se trata de recursividad, nada cambia. La declaración de return no sabe ni le importa si está regresando de una función invocada recursivamente, se comporta exactamente de la misma manera en cualquier caso.

De hecho, la recursividad no es nada "especial" en absoluto; se comporta exactamente de la misma manera que las llamadas a funciones ordinarias. Recibe información de lo que lo llamó por medio de argumentos, y devuelve información a la cosa que lo llamó al regresar. Si no devuelve algo (tal vez solo en un brazo de un if ), se devolverá None a su interlocutor, independientemente de si llama a cualquier otra función en esa rama, independientemente de lo que pueda devolver esa función si llama algo, e independientemente de si la función que llamas pasa a ser la misma función en la que estás dentro.