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.