Función para Factorial en Python


135

¿Cómo hago para calcular un factorial de un entero en Python?

Respuestas:


191

La forma más fácil es usar math.factorial(disponible en Python 2.6 y superior):

import math
math.factorial(1000)

Si quiere / tiene que escribirlo usted mismo, puede usar un enfoque iterativo:

def factorial(n):
    fact = 1
    for num in range(2, n + 1):
        fact *= num
    return fact

o un enfoque recursivo :

def factorial(n):
    if n < 2:
        return 1
    else:
        return n * factorial(n-1)

Tenga en cuenta que la función factorial solo se define para enteros positivos, por lo que también debe verificar eso n >= 0y eso isinstance(n, int). Si no es así, elevar ValueErrorao a TypeErrorrespectivamente. math.factorialse encargará de esto por ti.


2
No entiendo cómo puedes usar factorialdentro de la factorialfunción. ¿Cómo puede usar la misma función dentro de la función que está definiendo actualmente? Soy nuevo en Python, así que solo estoy tratando de entender.
J82

8
@ J82: El concepto utilizado aquí se llama recursión ( en.wikipedia.org/wiki/Recursion_(computer_science) ): una función que se llama a sí misma es perfectamente adecuada y, a menudo, útil.
schnaader

La función recursiva elevará a RecursionErrorpara cualquier número mayor que 998 (intente factorial(999)) a menos que aumente el límite de
Boris

114

En Python 2.6 y superior, intente:

import math
math.factorial(n)

Comenzando con Python 3.9 , pasar a floata esta función generará a DeprecationWarning. Si desea hacer eso, debe convertirlo na un intexplícito: math.factorial(int(n))que descartará cualquier cosa después del decimal, por lo que es posible que desee verificar eson.is_integer()
Boris el

25

No es realmente necesario ya que este es un hilo tan antiguo. Pero lo que hice aquí es otra forma de calcular el factorial de un número entero usando un ciclo while.

def factorial(n):
    num = 1
    while n >= 1:
        num = num * n
        n = n - 1
    return num

44
factorial (-1) devolverá 1, debería aumentar ValueError o algo así.
f.rodrigues

Esta función producirá resultados incorrectos si pasa un flotante con números después del decimal.
Boris

Con esta función, quiero imprimir factorial de los primeros cuatro enteros. Cuando cambio la num = num * nposición de la línea con n = n - 1y ejecuto esto for i in range(1, 5): print('Factorial of', i, 'is', factorial(i))Para cada factorial, la salida es 0. Me gustaría saber la razón por la que num = num * ndebe ser lo primero. ¡¡Gracias!!

18

Solución existente

La solución más corta y probablemente la más rápida es:

from math import factorial
print factorial(1000)

Construyendo tu propio

También puede crear su propia solución. Generalmente tienes dos enfoques. El que más me conviene es:

from itertools import imap
def factorial(x):
    return reduce(long.__mul__, imap(long, xrange(1, x + 1)))

print factorial(1000)

(funciona también para números más grandes, cuando el resultado se convierte long)

La segunda forma de lograr lo mismo es:

def factorial(x):
    result = 1
    for i in xrange(2, x + 1):
        result *= i
    return result

print factorial(1000)


5

Si está utilizando Python2.5 o anterior, intente

from operator import mul
def factorial(n):
    return reduce(mul, range(1,n+1))

para Python más nuevo, hay factorial en el módulo matemático como se da en otras respuestas aquí


Esta es una respuesta exclusiva de Python 2, reducese eliminó de Python 3.
Boris

@ Boris, en Python3 solo necesitas agregarfrom functools import reduce
John La Rooy

Fue eliminado por una razón, no deberías usarlo artima.com/weblogs/viewpost.jsp?thread=98196
Boris

5
def fact(n):
    f = 1
    for i in range(1, n + 1):
        f *= i
    return f

4

Usando un forbucle, contando hacia atrás desde n:

def factorial(n):
    base = 1
    for i in range(n, 0, -1):
        base = base * i
    print(base)

3

Por motivos de rendimiento, no utilice la recursividad. Sería desastroso.

def fact(n, total=1):
    while True:
        if n == 1:
            return total
        n, total = n - 1, total * n

Verificar resultados de ejecución

cProfile.run('fact(126000)')

4 function calls in 5.164 seconds

El uso de la pila es conveniente (como una llamada recursiva), pero tiene un costo: almacenar información detallada puede ocupar mucha memoria.

Si la pila es alta, significa que la computadora almacena mucha información sobre las llamadas a funciones.

El método solo ocupa memoria constante (como la iteración).

O usando for loop

def fact(n):
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

Verificar resultados de ejecución

cProfile.run('fact(126000)')

4 function calls in 4.708 seconds

O usando la función matemática incorporada

def fact(n):
    return math.factorial(n)

Verificar resultados de ejecución

cProfile.run('fact(126000)')

5 function calls in 0.272 seconds

1
Creo que este bucle while parece un poco más limpio <! - language: python -> def fact (n): ret = 1 while n> 1: n, ret = n - 1, ret * n return ret
edilio

1
def factorial(n):
    result = 1
    i = n * (n -1)
    while n >= 1:
        result = result * n
        n = n - 1
    return result

print (factorial(10)) #prints 3628800

1

Aquí está mi intento

>>> import math
>>> def factorial_verbose(number):
...     for i in range(number):
...             yield f'{i + 1} x '
...
>>> res = ''.join([x for x in factorial_verbose(5)])
>>> res = ' '.join([res[:len(res)-3], '=', str(math.factorial(5))])
>>> res
'1 x 2 x 3 x 4 x 5 = 120'

@Nir Levy, qué cosa tan divertida
Pedro Rodrigues el

1

Una línea, números rápidos y grandes también funciona:

#use python3.6.x for f-string
fact = lambda x: globals()["x"] if exec(f'x=1\nfor i in range(1, {x+1}):\n\tx*=i', globals()) is None else None

0

Sé que esto ha sido respondido, pero aquí hay otro método con una comprensión de la lista de rango inverso, lo que hace que el rango sea más fácil de leer y más compacto:

    #   1. Ensure input number is an integer by attempting to cast value to int
    #       1a. To accomplish, we attempt to cast the input value to int() type and catch the TypeError/ValueError 
    #           if the conversion cannot happen because the value type is incorrect
    #   2. Create a list of all numbers from n to 1 to then be multiplied against each other 
    #       using list comprehension and range loop in reverse order from highest number to smallest.
    #   3. Use reduce to walk the list of integers and multiply each against the next.
    #       3a. Here, reduce will call the registered lambda function for each element in the list.
    #           Reduce will execute lambda for the first 2 elements in the list, then the product is
    #           multiplied by the next element in the list, and so-on, until the list ends.

    try :
        num = int( num )
        return reduce( lambda x, y: x * y, [n for n in range(num, 0, -1)] )

    except ( TypeError, ValueError ) :
        raise InvalidInputException ( "Input must be an integer, greater than 0!" )

Puede ver una versión completa del código dentro de este resumen: https://gist.github.com/sadmicrowave/d4fbefc124eb69027d7a3131526e8c06


1
No es necesario usar [n for n in range(num, 0, -1)], rangeya es iterable.
Mark Mishyn

0

Otra forma de hacerlo es usar el que se np.prodmuestra a continuación:

def factorial(n):
    if n == 0:
        return 1
    else:
         return np.prod(np.arange(1,n+1))

0

Factorial de un entero positivo n, denotado por n !, es el producto de todos los enteros positivos menores o iguales a n.

Fórmula :n! = n * (n-1) * (n-2) * (n-3) * (n-4) * ....... * 1

Hay varios métodos para encontrar el factorial en python usando la función / biblioteca incorporada, etc. Aquí creé una función definida por el usuario con referencia a la definición básica de factorial.

def factorial(n):
    fact = 1
    for i in range(1,n+1):
        fact = fact * i
    return(fact)

print(factorial(4))

También podemos implementar la función factorial utilizando la recursivetécnica que se muestra a continuación. Pero este método solo es eficiente para valores enteros pequeños. Porque en la recursividad, la función se llama repetidamente y requiere un espacio de memoria para mantener la pila, que no es un enfoque eficiente u optimizado para valores enteros grandes para encontrar el factorial.

def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)

print(factorial(4))


0

En el siguiente código, estoy ingresando el número cuyo factorial quiero calcular, después de eso estoy multiplicando el -> número cuyo factorial queremos calcular con números que comienzan desde 1,2, ..., (número cuyo factorial Quiero calcular -1)

    f = int(input("Enter a number whose factorial you want to calculate = "))#Number 
                                           #whose factorial I want to calculate                              
for i in range(1,f): #assume I have taken f as 5
    f=f*i # In 1st iteration f=5*1 => 5 , in second iteration f = 5*2 => 10, 3rd 
          #iteration f = 10*3 =>30, 4th iteration f = 30*4 =>120  
print(f) #It will print the updated value of "f" i.e 120
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.