Calcular un factorial con Python: iterativo y recursivo

En este artículo aprenderás a calcular el factorial de un número entero con Python, usando bucles y recursividad.

Introducción

Por definición, un factorial es el producto de un número entero positivo y todos los números enteros positivos que son menores o iguales que el número dado. En otras palabras, obtener un factorial de un número significa multiplicar todos los números enteros desde ese número, hasta 1.

0! también es igual a 1, por convención.

Un factorial se denota con un número entero y va seguido de un signo de exclamación.

5! denota un factorial de cinco.

Y para calcular ese factorial, multiplicamos el número por cada número entero menor que él, hasta llegar a 1:

1
2
5! = 5 * 4 * 3 * 2 * 1
5! = 120

Teniendo en cuenta estas reglas, en este tutorial aprenderemos a calcular el factorial de un número entero con Python, usando bucles y recursividad. Comencemos con el cálculo del factorial usando bucles.

Cálculo factorial usando bucles

Podemos calcular factoriales utilizando tanto el bucle while como el bucle for. El proceso general es bastante similar para ambos. Todo lo que necesitamos es un parámetro como entrada y un contador.

Empecemos con el bucle for:

1
2
3
4
5
6
7
8
def get_factorial_for_loop(n):
    result = 1
    if n > 1:
        for i in range(1, n+1):
            result = result * i
        return result
    else:
        return 'n has to be positive'

Es posible que hayas notado que contamos desde 1 hasta n, mientras que la definición de factorial era desde el número dado hasta 1. Pero matemáticamente:

$$
1 * 2 * 3 * 4 ... * n = n * (n-1) * (n-2) * (n-3) * (n-4) .. * (n - (n-1))
$$

Para simplificar, (n - (n-1)) siempre será igual a 1.

Eso significa que no importa en qué dirección estemos contando. Puede comenzar desde 1 y aumentar hacia n, o puede comenzar desde n y disminuir hacia 1. Ahora que está aclarado, comencemos a desglosar la función que acabamos de escribir.

Nuestra función toma un parámetro n que denota el número para el que estamos calculando un factorial. Primero, definimos una variable llamada resultado y le asignamos 1 como valor.

¿Por qué asignar 1 y no 0 te preguntas?

Porque si tuviéramos que asignarle 0, todas las siguientes multiplicaciones con 0, naturalmente, darían como resultado un enorme 0.

Luego comenzamos nuestro bucle for en el rango de 1 a n+1. Recuerde, el rango de Python se detendrá antes del segundo argumento. Para incluir también el último número, simplemente agregamos un 1 adicional.

Dentro del ciclo for, multiplicamos el valor actual de resultado con el valor actual de nuestro índice i.

Finalmente, devolvemos el valor final del resultado. Probemos nuestra función imprima el resultado:

1
2
3
4
inp = input("Enter a number: ")
inp = int(inp)

print(f"The result is: {get_factorial_for_loop(inp)}")

If you'd like to read more about how to get user input, read our Obtener la entrada del usuario en Python.

Le pedirá al usuario que dé su entrada. Lo intentaremos con 4:

1
2
Enter a number: 4
The result is: 24

Puedes usar una calculadora para verificar el resultado:

4! es 4 * 3 * 2 * 1, lo que da como resultado 24.

Ahora veamos cómo podemos calcular el factorial usando el bucle while. Aquí está nuestra función modificada:

1
2
3
4
5
6
def get_factorial_while_loop(n):
    result = 1
    while n > 1:
        result = result * n
        n -= 1
    return result

Esto es bastante similar al bucle for. Excepto por esta vez, nos estamos moviendo de n hacia 1, más cerca de la definición matemática. Probemos nuestra función:

1
2
3
4
inp = input("Enter a number: ")
inp = int(inp)

print(f"The result is: {get_factorial_while_loop(inp)}")

Introduciremos 4 como entrada una vez más:

1
2
Enter a number: 4
The result is: 24

Aunque el cálculo fue 4 * 3 * 2 * 1, el resultado final es el mismo que antes.

Calcular factoriales usando bucles fue fácil. Ahora echemos un vistazo a cómo calcular el factorial usando una función recursiva.

Cálculo factorial mediante recursión

Una función recursiva es una función que se llama a sí misma. Puede parecer un poco intimidante al principio, pero ten paciencia con nosotros y verás que las funciones recursivas son fáciles de entender.

En general, cada función recursiva tiene dos componentes principales: un caso base y un paso recursivo.

Los casos base son las instancias más pequeñas del problema. También una ruptura, un caso que devolverá un valor y saldrá de la recursividad. En términos de funciones factoriales, el caso base es cuando devolvemos el elemento final del factorial, que es 1.

Sin un caso base o con un caso base incorrecto, su función recursiva puede ejecutarse infinitamente, provocando un desbordamiento.

Los pasos recursivos, como su nombre lo indica, son la parte recursiva de la función, donde todo el problema se transforma en algo más pequeño. Si el paso recursivo no logra reducir el problema, entonces nuevamente la recursividad puede ejecutarse infinitamente.

Considere la parte recurrente de los factoriales:

  • 5! es 5 * 4 * 3 * 2 * 1.

Pero también sabemos que:

  • 4 * 3 * 2 * 1 es 4!.

En otras palabras, 5! es 5 * 4! y 4! es 4 * 3! y así sucesivamente.

Entonces podemos decir que n! = n * (n-1)!. ¡Este será el paso recursivo de nuestro factorial!

Una recursividad factorial termina cuando llega a 1. Este será nuestro caso base. Devolveremos 1 si n es 1 o menos, cubriendo la entrada cero.

Echemos un vistazo a nuestra función factorial recursiva:

1
2
3
4
5
def get_factorial_recursively(n):
    if n <= 1:
        return 1
    else:
        return n * get_factorial_recursively(n-1)

Como puede ver, el bloque if encarna nuestro caso base, mientras que el bloque else cubre el paso recursivo.

Probemos nuestra función:

1
2
3
4
inp = input("Enter a number: ")
inp = int(inp)

print(f"The result is: {get_factorial_recursively(inp)}")

Introduciremos 3 como entrada esta vez:

1
2
Enter a number:3
The result is: 6

Obtenemos el mismo resultado. Pero esta vez, lo que pasa bajo el capó es bastante interesante:

Verá, cuando ingresamos la entrada, la función verificará con el bloque si, y dado que 3 es mayor que 1, saltará al bloque else. En este bloque, vemos la línea return n * get_factorial_recursively(n-1).

Conocemos el valor actual de n por el momento, es 3, pero get_factorial_recursively(n-1) aún no se ha calculado.

Luego, el programa llama a la misma función una vez más, pero esta vez nuestra función toma 2 como parámetro. Verifica el bloque if y salta al bloque else y nuevamente se encuentra con la última línea. Ahora, el valor actual de n es 2 pero el programa todavía debe calcular get_factorial_recursively(n-1).

Entonces llama a la función una vez más, pero esta vez el bloque if, o más bien, la clase base logra devolver 1 y sale de la recursividad.

Siguiendo el mismo patrón hacia arriba, devuelve el resultado de cada función, multiplicando el resultado actual con la n anterior y devolviéndolo por la llamada de función anterior. En otras palabras, nuestro programa primero llega al final del factorial (que es 1), luego va aumentando, mientras se multiplica en cada paso.

También eliminando la función de la pila de llamadas una por una, hasta que se devuelva el resultado final de n * (n-1).

Así es generalmente como funcionan las funciones recursivas. Algunos problemas más complicados pueden requerir recursiones más profundas con más de un caso base o más de un paso recursivo. ¡Pero por ahora, esta simple recursión es lo suficientemente buena para resolver nuestro problema factorial!

If you'd like to learn more about recursion in Python, read our Guía para comprender la recursividad en Python!

Conclusión

En este artículo, cubrimos cómo calcular factoriales usando bucles for y while. También aprendimos qué es la recursión y cómo calcular el factorial usando la recursión.

Si te ha gustado la recursividad y quieres practicar más, ¡intenta calcular la sucesión de Fibonacci con la recursividad! Y si tiene alguna pregunta o comentario sobre nuestro artículo, no dude en compartirlo en la sección de comentarios.