Função para fatorial em Python


135

Como faço para calcular um fatorial de um número inteiro em Python?

Respostas:


191

A maneira mais fácil é usar math.factorial(disponível no Python 2.6 e acima):

import math
math.factorial(1000)

Se você quiser / tiver que escrever você mesmo, poderá usar uma abordagem iterativa:

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

ou uma abordagem recursiva :

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

Observe que a função fatorial é definida apenas para números inteiros positivos; portanto, você também deve verificar isso n >= 0e aquilo isinstance(n, int). Caso contrário, aumente um ValueErrorou um, TypeErrorrespectivamente. math.factorialvai cuidar disso para você.


2
Não estou entendendo como você pode usar factorialdentro da factorialfunção. Como você pode usar a mesma função na função que está definindo atualmente? Eu sou novo no Python, então só estou tentando entender.
J82

8
@ J82: O conceito usado aqui é chamado de recursão ( en.wikipedia.org/wiki/Recursion_(computer_science) ) - uma função que se chama é perfeitamente bem e frequentemente útil.
schnaader

A função recursiva aumentará um RecursionErrorpara qualquer número maior que 998 (tentativa factorial(999)), a menos que você aumente o limite de recursão do Python
Boris

114

No Python 2.6 e superior, tente:

import math
math.factorial(n)

Começando com o Python 3.9 , passar a floatpara esta função aumentará a DeprecationWarning. Se você quiser fazer isso, precisará converter npara um intexplicitamente:, math.factorial(int(n))que descartará qualquer coisa após o decimal, para que você possa verificar isso:n.is_integer()
Boris

25

Não é realmente necessário, pois esse é um tópico tão antigo. Mas eu fiz aqui é outra maneira de calcular o fatorial de um número inteiro usando um loop while.

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

4
fatorial (-1) retornará 1, deve aumentar ValueError ou algo assim.
f.rodrigues

Esta função produzirá resultados incorretos se você passar um número flutuante com números após o decimal.
Boris

Com esta função, quero imprimir o fatorial dos quatro primeiros inteiros. Quando troco a num = num * nposição da linha com n = n - 1e executo isso for i in range(1, 5): print('Factorial of', i, 'is', factorial(i))Para cada fatorial, o resultado é 0. Gostaria de saber o raciocínio do porquê num = num * nprecisa vir primeiro. Obrigado!!

18

Solução existente

A solução mais curta e provavelmente a mais rápida é:

from math import factorial
print factorial(1000)

Construindo seu próprio

Você também pode criar sua própria solução. Geralmente você tem duas abordagens. O que melhor me convém é:

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

print factorial(1000)

(funciona também para números maiores, quando o resultado se torna long)

A segunda maneira de conseguir o mesmo é:

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

print factorial(1000)


5

Se você estiver usando o Python2.5 ou mais antigo, tente

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

para Python mais recente, há fatorial no módulo de matemática, conforme indicado em outras respostas aqui


Este é um 2-única resposta Python, reducefoi removida a partir do Python 3.
Boris

@Boris, em Python3 você só precisa adicionarfrom functools import reduce
John La Rooy

Ele foi removido por uma razão, você não deve usá-lo 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 um forloop, contando de trás para frente n:

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

3

Por razões de desempenho, não use recursão. Seria desastroso.

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

Verifique os resultados em execução

cProfile.run('fact(126000)')

4 function calls in 5.164 seconds

O uso da pilha é conveniente (como chamada recursiva), mas tem um custo: o armazenamento de informações detalhadas pode consumir muita memória.

Se a pilha estiver alta, significa que o computador armazena muitas informações sobre chamadas de função.

O método ocupa apenas memória constante (como iteração).

Ou usando o loop for

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

Verifique os resultados em execução

cProfile.run('fact(126000)')

4 function calls in 4.708 seconds

Ou Usando a função matemática integrada

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

Verifique os resultados em execução

cProfile.run('fact(126000)')

5 function calls in 0.272 seconds

1
Eu acho que esse loop while parece um pouco mais limpo <! - 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

Aqui está a minha tentativa

>>> 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, que coisinha divertida #
Pedro Rodrigues

1

Uma linha, números rápidos e grandes também 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

Eu sei que isso foi respondido, mas aqui está outro método com uma compreensão de lista de intervalo reverso, tornando o intervalo mais fácil de ler e mais 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!" )

Você pode ver uma versão completa do código nesta lista: https://gist.github.com/sadmicrowave/d4fbefc124eb69027d7a3131526e8c06


1
Não há necessidade de usar [n for n in range(num, 0, -1)], rangejá é iterável.
Mark Mishyn 12/01

0

Outra maneira de fazer isso é usar o np.prodmostrado abaixo:

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

0

O fatorial de um número inteiro positivo n, denotado por n !, é o produto de todos os números inteiros positivos menores ou iguais a n.

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

Existem vários métodos para encontrar o fatorial em python usando a função / biblioteca incorporada etc. Aqui, criei uma função definida pelo usuário com referência à definição básica de fatorial.

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

print(factorial(4))

Também podemos implementar a função fatorial usando a recursivetécnica mostrada abaixo. Mas esse método é eficiente apenas para valores inteiros pequenos. Como na recursão, a função é chamada repetidamente e requer um espaço de memória para manter a pilha, o que não é uma abordagem eficiente ou otimizada para que valores inteiros grandes encontrem o fatorial.

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

print(factorial(4))


0

No código abaixo, estou inserindo o número cujo fatorial eu quero calcular. Depois disso, multiplico o número -> cujo fatorial queremos calcular com números a partir de 1,2, ...., (número cujo fatorial Eu quero 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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.