Fonction pour factorielle en Python

135

Comment calculer une factorielle d'un entier en Python?

Nir Levy
la source

Réponses:

191

Le moyen le plus simple est d'utiliser math.factorial(disponible dans Python 2.6 et supérieur):

import math
math.factorial(1000)

Si vous voulez / devez l'écrire vous-même, vous pouvez utiliser une approche itérative:

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

ou une approche récursive :

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

Notez que la fonction factorielle n'est définie que pour les entiers positifs, vous devez donc également vérifier cela n >= 0et cela isinstance(n, int). Si ce n'est pas le cas, augmentez respectivement a ValueErrorou a TypeError. math.factorialprendra soin de cela pour vous.

schnaader
la source
2
Je ne comprends pas comment vous pouvez utiliser factorialdans la factorialfonction. Comment pouvez-vous utiliser la même fonction dans la fonction que vous définissez actuellement? Je suis nouveau sur Python donc j'essaye juste de comprendre.
J82
8
@ J82: Le concept utilisé ici est appelé récursivité ( en.wikipedia.org/wiki/Recursion_(computer_science) ) - une fonction s'appelant elle-même est parfaitement bien et souvent utile.
schnaader
La fonction récursive lèvera a RecursionErrorpour tout nombre supérieur à 998 (essayez factorial(999)) à moins que vous n'augmentiez la limite de récursivité de Python
Boris
114

Sur Python 2.6 et supérieur, essayez:

import math
math.factorial(n)
Joril
la source
À partir de Python 3.9 , passer a floatà cette fonction lèvera un DeprecationWarning. Si vous voulez faire cela, vous devez convertir explicitement en nun int:, math.factorial(int(n))qui supprimera tout ce qui suit la décimale, vous voudrez peut-être vérifier celan.is_integer()
Boris
25

Pas vraiment nécessaire car c'est un fil si vieux. Mais j'ai fait ici une autre façon de calculer la factorielle d'un entier en utilisant une boucle while.

def factorial(n):
    num = 1
    while n >= 1:
        num = num * n
        n = n - 1
    return num
ciziar
la source
4
factorial (-1) renverra 1, devrait lever ValueError ou quelque chose.
f.rodrigues
Cette fonction produira des résultats incorrects si vous passez un flottant avec des nombres après la décimale.
Boris
Avec cette fonction, je veux imprimer la factorielle des quatre premiers entiers. Quand j'échange la num = num * nposition de ligne avec n = n - 1et que j'exécute ceci for i in range(1, 5): print('Factorial of', i, 'is', factorial(i))Pour chaque factoriel, le résultat est 0. Je voudrais savoir pourquoi il num = num * nfaut passer en premier. Merci!!
18

Solution existante

La solution la plus courte et probablement la plus rapide est:

from math import factorial
print factorial(1000)

Construire le vôtre

Vous pouvez également créer votre propre solution. En général, vous avez deux approches. Celui qui me convient le mieux est:

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

print factorial(1000)

(cela fonctionne aussi pour des nombres plus grands, lorsque le résultat devient long)

La deuxième façon d'y parvenir est:

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

print factorial(1000)
Tadeck
la source
5

Si vous utilisez Python2.5 ou une version antérieure, essayez

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

pour Python plus récent, il y a factoriel dans le module mathématique comme indiqué dans d'autres réponses ici

John La Rooy
la source
Ceci est une réponse Python 2 uniquement, a reduceété supprimée de Python 3.
Boris
@Boris, en Python3, il vous suffit d'ajouterfrom functools import reduce
John La Rooy
Il a été supprimé pour une raison, vous ne devriez pas l'utiliser 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
Jordan
la source
4

En utilisant une forboucle, en comptant à rebours depuis n:

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

Pour des raisons de performances, veuillez ne pas utiliser la récursivité. Ce serait désastreux.

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

Vérifier les résultats en cours

cProfile.run('fact(126000)')

4 function calls in 5.164 seconds

L'utilisation de la pile est pratique (comme un appel récursif), mais cela a un coût: stocker des informations détaillées peut prendre beaucoup de mémoire.

Si la pile est élevée, cela signifie que l'ordinateur stocke beaucoup d'informations sur les appels de fonction.

La méthode n'occupe que la mémoire constante (comme l'itération).

Ou en utilisant la boucle for

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

Vérifier les résultats en cours

cProfile.run('fact(126000)')

4 function calls in 4.708 seconds

Ou en utilisant les fonctions mathématiques intégrées

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

Vérifier les résultats en cours

cProfile.run('fact(126000)')

5 function calls in 0.272 seconds
binbjz
la source
1
Je pense que cette boucle while a l'air un peu plus propre <! - 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

la source
1

Voici mon essai

>>> 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'
Pedro Rodrigues
la source
@Nir Levy, quelle petite chose amusante
Pedro Rodrigues
1

Une ligne, des nombres rapides et grands fonctionne également:

#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
Jundullah
la source
0

Je sais que cela a été répondu, mais voici une autre méthode avec une compréhension de liste de plage inversée, rendant la plage plus facile à lire et plus compacte:

    #   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!" )

Vous pouvez voir une version complète du code dans cet essentiel: https://gist.github.com/sadmicrowave/d4fbefc124eb69027d7a3131526e8c06

triste
la source
1
Pas besoin d'utiliser [n for n in range(num, 0, -1)], rangeest déjà itérable.
Mark Mishyn le
0

Une autre façon de le faire est d'utiliser np.prodci-dessous:

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

Factorielle d'un entier positif n, noté n !, est le produit de tous les nombres entiers positifs inférieurs ou égaux à n.

Formule :n! = n * (n-1) * (n-2) * (n-3) * (n-4) * ....... * 1

Il existe plusieurs méthodes pour trouver la factorielle en python en utilisant la fonction / bibliothèque intégrée, etc. Ici, j'ai créé une fonction définie par l'utilisateur avec référence à la définition de base de la factorielle.

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

print(factorial(4))

Nous pouvons également implémenter la fonction factorielle en utilisant la recursivetechnique ci-dessous. Mais cette méthode n'est efficace que pour les petites valeurs entières. Parce qu'en récursion, la fonction est appelée à plusieurs reprises et nécessite un espace mémoire pour maintenir la pile, ce qui n'est pas une approche efficace ou optimisée pour les grandes valeurs entières pour trouver la factorielle.

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

print(factorial(4))
Usman
la source
0
def factorial(n):
mul = 1
for i in range( 1, n + 1):
    mul *= i
print(factorial(6))
Jitendra Bhalothia
la source
Une autre question à se poser est ce que cela ajoute aux 17 autres réponses.
pppery
Cette réponse est un double de cette réponse existante: stackoverflow.com/a/5136481
Karel
0

Dans le code ci-dessous, je prends l'entrée du nombre dont je veux calculer la factorielle, après cela je multiplie le -> nombre dont nous voulons calculer la factorielle avec des nombres à partir de 1,2, ...., (nombre dont la factorielle Je veux calculer -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
Rajat
la source