Funzione per fattoriale in Python


135

Come posso fare per calcolare un fattoriale di un numero intero in Python?

Risposte:


191

Il modo più semplice è usare math.factorial(disponibile in Python 2.6 e versioni successive):

import math
math.factorial(1000)

Se vuoi / devi scriverlo tu stesso, puoi usare un approccio iterativo:

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

o un approccio ricorsivo :

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

Nota che la funzione fattoriale è definita solo per numeri interi positivi, quindi dovresti anche controllare quello n >= 0e quello isinstance(n, int). In caso contrario, aumentare rispettivamente a ValueErroro a TypeError. math.factorialse ne occuperà per te.


2
Non capisco come è possibile utilizzare factorialall'interno della factorialfunzione. Come puoi usare la stessa funzione all'interno della funzione che stai attualmente definendo? Sono nuovo di Python, quindi sto solo cercando di capire.
J82,

8
@ J82: il concetto usato qui si chiama ricorsione ( en.wikipedia.org/wiki/Recursion_(computer_science) ) - una funzione che si chiama è perfettamente perfetta e spesso utile.
Schnaader,

La funzione ricorsiva aumenterà a RecursionErrorper qualsiasi numero maggiore di 998 (prova factorial(999)) a meno che tu non aumenti il ​​limite di ricorsione di Python
Boris

114

Su Python 2.6 e versioni successive, prova:

import math
math.factorial(n)

A partire da Python 3.9 , passando a floata questa funzione genererà a DeprecationWarning. Se vuoi farlo, devi convertirlo nin intesplicitamente math.factorial(int(n)):, che eliminerà qualsiasi cosa dopo il decimale, quindi potresti voler controllare chen.is_integer()
Boris

25

Non proprio necessario poiché si tratta di un thread così vecchio. Ma ho fatto qui è un altro modo per calcolare il fattoriale di un numero intero usando un ciclo while.

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

4
factorial (-1) restituirà 1, dovrebbe aumentare ValueError o qualcosa del genere.
f.rodrigues,

Questa funzione produrrà risultati errati se si passa in un float con numeri dopo il decimale.
Boris,

Con questa funzione, voglio stampare il fattoriale dei primi quattro numeri interi. Quando cambio la num = num * nposizione della linea con n = n - 1ed eseguo questo for i in range(1, 5): print('Factorial of', i, 'is', factorial(i))Per ciascun Fattoriale, l'output è 0. Vorrei sapere la logica del motivo num = num * nper cui deve venire prima. Grazie!!

18

Soluzione esistente

La soluzione più breve e probabilmente la più veloce è:

from math import factorial
print factorial(1000)

Costruisci il tuo

Puoi anche creare la tua soluzione. Generalmente hai due approcci. Quello che mi si addice meglio è:

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

print factorial(1000)

(funziona anche per numeri più grandi, quando il risultato diventa long )

Il secondo modo per ottenere lo stesso è:

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

print factorial(1000)


5

Se stai usando Python2.5 o precedente, prova

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

per il nuovo Python, c'è un fattoriale nel modulo di matematica come indicato in altre risposte qui


Questa è una sola risposta di Python 2, è reducestata rimossa da Python 3.
Boris il

@Boris, in Python3 devi solo aggiungerefrom functools import reduce
John La Rooy,

È stato rimosso per un motivo, non dovresti 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 for-loop, contando all'indietro da n:

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

3

Per motivi di prestazioni, non utilizzare la ricorsione. Sarebbe disastroso.

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

Controlla i risultati della corsa

cProfile.run('fact(126000)')

4 function calls in 5.164 seconds

L'uso dello stack è conveniente (come una chiamata ricorsiva), ma ha un costo: la memorizzazione di informazioni dettagliate può richiedere molta memoria.

Se lo stack è alto, significa che il computer memorizza molte informazioni sulle chiamate di funzione.

Il metodo occupa solo memoria costante (come l'iterazione).

O usando per il ciclo

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

Controlla i risultati della corsa

cProfile.run('fact(126000)')

4 function calls in 4.708 seconds

O utilizzando la funzione matematica integrata

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

Controlla i risultati della corsa

cProfile.run('fact(126000)')

5 function calls in 0.272 seconds

1
Penso che questo mentre il ciclo appaia un po 'più pulito <! - 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

Ecco il mio tentativo

>>> 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, che piccola cosa divertente
Pedro Rodrigues il

1

Una riga, numeri veloci e grandi funziona anche:

#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

So che è stata data una risposta, ma ecco un altro metodo con una comprensione dell'elenco di intervalli inversi, che rende l'intervallo più facile da leggere e più compatto:

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

Puoi vedere una versione completa del codice all'interno di questa sintesi: https://gist.github.com/sadmic Microwave/ d4fbefc124eb69027d7a3131526e8c06


1
Non c'è bisogno di usare [n for n in range(num, 0, -1)], rangeè già iterabile.
Mark Mishyn, il

0

Un altro modo per farlo è utilizzare np.prodmostrato di seguito:

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

0

Fattoriale di un intero positivo n, indicato da n !, è il prodotto di tutti gli interi positivi minori o uguali a n.

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

Esistono diversi metodi per trovare il fattoriale in Python usando la funzione / libreria incorporata ecc. Qui ho creato una funzione definita dall'utente con riferimento alla definizione base di fattoriale.

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

print(factorial(4))

Possiamo anche implementare la funzione fattoriale usando la recursivetecnica come mostrato di seguito. Ma questo metodo è efficace solo per valori interi di piccole dimensioni. Perché in ricorsione, la funzione è chiamata ripetutamente e richiede uno spazio di memoria per mantenere lo stack che non è un approccio efficiente o ottimizzato per valori fattoriali di grandi dimensioni per trovare il fattoriale.

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

print(factorial(4))


0

Nel seguente codice, sto prendendo input del numero di cui voglio calcolare il fattoriale, dopodiché sto moltiplicando il -> numero di cui vogliamo calcolare il fattoriale con numeri che iniziano da 1,2, ...., (numero di cui fattoriale Voglio calcolare -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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.