Básicamente, una función recursiva es una función que se llama a sí misma en el proceso de ejecución. Su funcionamiento es muy similar a la iteraciones que vimos en clase pasadas. Comenzaremos trabajando con el siguiente ejemplo que posteriormente explicaremos paso a paso:
# Cuenta regresiva
def cuentaRegresiva(x):
x -= 1
if x >= 0:
print(x)
cuentaRegresiva(x)
else:
print('Fin')
cuentaRegresiva(4)
3 2 1 0 Fin
donde
x=4
procedemos a quitarle uno y volver a asignar este valor a la variable x
, de tal manera x=3
, después imprimimos este valor y posteriormente volvemos a aplicar la función cuentaRegresiva(x)
x=3
ingresa a nuestra función por lo que se le resta uno y se le vuelve a asignar este valor, es así como x=2
y es impreso este valor, luego, nuevamente es ingresado en la función cuentaRegresiva(x)
.Continuaremos con este procedimiento hasta que x=0
pues, una vez que dicho valor es impreso y es ingresado a la función cuentaRegresiva(x)
, una vez que le quitemos uno tendremos como resultado x=-1
por lo que pasaremos a la ejecución del código correspondiente al else
de nuestro condicional if
, lo cual regresa el mensaje 'Fin'
.
Podemos ver otro ejemplo sobre funciones recursivas en Python utilizando el factorial de un número. Recordemos que dado $n\in\mathbb{N}$ tenemos que
$$ n!=n(n-1)\cdots3\cdot2\cdot1 $$Ahora, podemos implemenar lo anterior mediante funciones recursivas:
# definimos la función
def factorial(n):
if n == 0 or n == 1:
resultado = 1
elif n > 1:
resultado = n * factorial(n - 1)
return resultado
# probamos nuestra función
factorial(5)
120
donde al ingresar el 5 a la función obtenemos que resultado = 5 * factorial(4)
, luego al asignarle el 4 a la función tendremos que resultado = 4 * factorial(3)
y así hasta obtener que resultado = 2 * factorial(1)
, donde factorial(1)
retorna como resultado 1 y por ende tendremos que
resultado = 5 * 4 * 3 * 2 * 1
o lo que es lo mismo obtenemos el valor de resultado
final el cual es 120.
Veamos que
factorial(4)
24
también puede explicarse observando que
Para finalizar volvamos a ver la función recursiva que nos arroja el factorial de un número, observando cuidadosamente cada ejecución cuando llamamos a dicha función:
# definimos la función
def factorial(n):
print("Número en ejecución", n)
if n == 0 or n == 1:
resultado = 1
elif n > 1:
resultado = n * factorial(n - 1)
print("Resultado", resultado)
return resultado
# probamos nuestra función
factorial(5)
Número en ejecución 5 Número en ejecución 4 Número en ejecución 3 Número en ejecución 2 Número en ejecución 1 Resultado 2 Resultado 6 Resultado 24 Resultado 120
120
Notemos que primero se imprime el mensaje Número de ejecución 5 y ejecutaremos las líneas de código referentes al elif
(es importante recordar que la ejecución en Python es de arriba a abajo línea por línea), sin embargo cuando estemos en la línea de ejecución resultado = n * factorial(n - 1)
tendremos que resultado = 5 * factorial(4)
y la función factorial()
se volvera a llamar por lo que no se ejecutara en ese momento la línea siguiente print("Resultado", resultado)
. De tal manera, en este bloque tendremos pendiente obtener resultado = 5 * factorial(4)
.
Una vez pasado al siguiente bloque de ejecución se imprime el mensaje Número de ejecución 4 y tendremos la ejecución de la línea de código resultado = 4 * factorial(3)
la cual quedará pendiente y además la función se vuelve a llamar.
Una vez pasado al siguiente bloque de ejecución se imprime el mensaje Número de ejecución 3 y tendremos la ejecución de la línea de código resultado = 3 * factorial(2)
la cual quedará pendiente y además la función se vuelve a llamar.
Una vez pasado al siguiente bloque de ejecución se imprime el mensaje Número de ejecución 2 y tendremos la ejecución de la línea de código resultado = 2 * factorial(1)
la cual quedará pendiente y además la función se vuelve a llamar.
Continuando con este procedimiento se imprime el mensaje Número de ejecución 1 y en este caso se ejecutará la línea de código dentro de la condición del if
, esto es resultado = 1
. De ahí pasamos a la línea return resultado
lo cual arroja de llamar a la función factorial(1)
el valor de 1 por lo dicho anteriormente. Una vez que ya tenemos un resultado fijo se procede a dar el resultado de las operaciones que quedaron pendientes.
De inmediato regresamos a la línea que quedó pendiente de ejecución resultado = 2 * factorial(1)
lo cual asigna el valor de 2 en la variable resultado
y después se ejecuta la línea inmediata siguiente print("Resultado", 2)
. Es así como tenemos que, al llamar la función factorial(2)
, se nos regresa como resultado el valor de 2.
Luego ejecutamos resultado = 3 * factorial(2)
el cual asigna el valor de 6 a la variable resultado
pues factorial(2)
arroja el valor de 2. Después se imprime print("Resultado", 6)
. Y así sucesivamente.
Finalmente vamos a crear un función recursiva para calcular los números de fibonacci. Recordemos que el n-ésimo número de Fibonacci se obtiene a partir de los dos anteriores, esto es:
$$ F_{n}=F_{n-1}+F_{n-2}, \ \ \ n \geq 2 $$Por ejemplo, tomando los primeros dos números de la sucesión de Fibonacci $1$ y $1$ podemos obtener el tercer término el cual es $1+1=2$, el cuarto término el cual es $1+2=3$, el quinto término el cual es $2+3=5$, etcétera.
Lo que haremos será que nuestra función devuelva 1 cuando el término a buscar ($n$) sea 1 ó 2 y en los demás casos devolverá el valor de fibonacci(n-1) + fibonacci(n-2)
. Por ejemplo, si $n=4$ entonces la función devolverá el valor de fibonacci(3) + fibonacci(2)
que es lo mismo que fibonacci(3) + 1
. Luego, para obtener fibonacci(3)
se tedrá que la función devolverá el valor de resultante de fibonacci(2) + fibonacci(1)
lo cual equivale a $1+1=2$ y por ende, regresando a la ejecución pendiente fibonacci(3) + fibonacci(2)
tendremos el valor de $2+1=3$. Lo anterior se puede implementar en código como sigue:
# Definimos la función
def fibonacci(n):
if n == 1:
# el primer término de la sucesión es el 1
return n
elif n == 2:
# el segundo término de la sucesión es el 1
return n - 1
return fibonacci(n-1) + fibonacci(n-2)
# probamos nuestra función
for i in range(1,7):
print(f'El término {i} de la sucesión es: {fibonacci(i)}')
El término 1 de la sucesión es: 1 El término 2 de la sucesión es: 1 El término 3 de la sucesión es: 2 El término 4 de la sucesión es: 3 El término 5 de la sucesión es: 5 El término 6 de la sucesión es: 8