Funktion für Factorial in Python

135

Wie berechne ich eine Fakultät einer Ganzzahl in Python?

Nir Levy
quelle

Antworten:

191

Am einfachsten ist die Verwendung math.factorial(verfügbar in Python 2.6 und höher):

import math
math.factorial(1000)

Wenn Sie es selbst schreiben möchten / müssen, können Sie einen iterativen Ansatz verwenden:

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

oder ein rekursiver Ansatz:

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

Beachten Sie, dass die Fakultätsfunktion nur für positive Ganzzahlen definiert ist. Überprüfen Sie daher auch dies n >= 0und das isinstance(n, int). Wenn nicht, erhöhen Sie ein ValueErroroder ein TypeError. math.factorialwird sich für Sie darum kümmern.

Schnaader
quelle
2
Ich verstehe nicht, wie Sie factorialinnerhalb der factorialFunktion verwenden können. Wie können Sie dieselbe Funktion in der Funktion verwenden, die Sie gerade definieren? Ich bin neu in Python, also versuche ich nur zu verstehen.
J82
8
@ J82: Das hier verwendete Konzept heißt Rekursion ( en.wikipedia.org/wiki/Recursion_(computer_science) ) - eine Funktion, die sich selbst aufruft, ist vollkommen in Ordnung und oft nützlich.
Schnaader
Die rekursive Funktion erhöht a RecursionErrorfür eine beliebige Zahl größer als 998 (Versuch factorial(999)), es sei denn, Sie erhöhen Pythons Rekursionslimit
Boris
114

Versuchen Sie unter Python 2.6 und höher:

import math
math.factorial(n)
Joril
quelle
Wenn Sie ab Python 3.9 a floatan diese Funktion übergeben, wird a ausgelöst DeprecationWarning. Wenn Sie das tun möchten, müssen Sie nin ein intexplizites konvertieren : math.factorial(int(n)), das alles nach der Dezimalstelle verwirft, also möchten Sie das vielleicht überprüfenn.is_integer()
Boris
25

Nicht wirklich notwendig, da dies ein so alter Thread ist. Aber ich habe hier eine andere Möglichkeit, die Fakultät einer ganzen Zahl mit einer while-Schleife zu berechnen.

def factorial(n):
    num = 1
    while n >= 1:
        num = num * n
        n = n - 1
    return num
ciziar
quelle
4
Fakultät (-1) gibt 1 zurück, sollte ValueError oder so etwas auslösen.
f.rodrigues
Diese Funktion führt zu falschen Ergebnissen, wenn Sie einen Gleitkommawert mit Zahlen nach der Dezimalstelle übergeben.
Boris
Mit dieser Funktion möchte ich die Fakultät der ersten vier ganzen Zahlen ausdrucken. Wenn ich die Zeilenposition num = num * nmit tausche n = n - 1und dies for i in range(1, 5): print('Factorial of', i, 'is', factorial(i))für jedes Faktor ausführe , ist die Ausgabe 0. Ich möchte wissen, warum dies num = num * nzuerst geschehen muss. Vielen Dank!!
18

Bestehende Lösung

Die kürzeste und wahrscheinlich schnellste Lösung ist:

from math import factorial
print factorial(1000)

Bauen Sie Ihre eigenen

Sie können auch Ihre eigene Lösung erstellen. Im Allgemeinen haben Sie zwei Ansätze. Das, was mir am besten passt, ist:

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

print factorial(1000)

(Es funktioniert auch für größere Zahlen, wenn das Ergebnis wird long)

Der zweite Weg, dies zu erreichen, ist:

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

print factorial(1000)
Tadeck
quelle
7
def factorial(n):
    if n < 2:
        return 1
    return n * factorial(n - 1)
Nishanth
quelle
1
factorial(999)(und höher) wird ein erhöhen, es RuntimeErrorsei denn, Sie erhöhen Pythons Rekursionslimit
Boris
5

Wenn Sie Python2.5 oder älter verwenden, versuchen Sie es

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

Für neueres Python gibt es eine Fakultät im Mathematikmodul, wie in anderen Antworten hier angegeben

John La Rooy
quelle
Dies ist eine reine Python 2-Antwort, reducedie aus Python 3 entfernt wurde.
Boris
@ Boris, in Python3 müssen Sie nur hinzufügenfrom functools import reduce
John La Rooy
Es wurde aus einem Grund entfernt, Sie sollten es nicht verwenden 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
Jordanien
quelle
4

Mit einer forSchleife rückwärts zählen von n:

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

Verwenden Sie aus Leistungsgründen keine Rekursion. Es wäre katastrophal.

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

Überprüfen Sie die Laufergebnisse

cProfile.run('fact(126000)')

4 function calls in 5.164 seconds

Die Verwendung des Stapels ist praktisch (wie ein rekursiver Aufruf), hat jedoch Kosten: Das Speichern detaillierter Informationen kann viel Speicherplatz beanspruchen.

Wenn der Stapel hoch ist, bedeutet dies, dass der Computer viele Informationen über Funktionsaufrufe speichert.

Die Methode belegt nur konstanten Speicher (wie Iteration).

Oder Verwenden der for-Schleife

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

Überprüfen Sie die Laufergebnisse

cProfile.run('fact(126000)')

4 function calls in 4.708 seconds

Oder Verwenden der integrierten Funktionsmathematik

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

Überprüfen Sie die Laufergebnisse

cProfile.run('fact(126000)')

5 function calls in 0.272 seconds
binbjz
quelle
1
Ich denke, diese while-Schleife sieht ein bisschen sauberer aus. <! - language: python -> def fact (n): ret = 1, während 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

quelle
1

Hier ist mein Versuch

>>> 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
quelle
@Nir Levy, was für eine lustige kleine Sache
Pedro Rodrigues
1

Eine Zeile, schnelle und große Zahlen funktionieren auch:

#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
quelle
0

Ich weiß, dass dies beantwortet wurde, aber hier ist eine andere Methode mit einem Verständnis der umgekehrten Bereichsliste, die den Bereich leichter lesbar und kompakter macht:

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

Sie können eine Vollversion des Codes in dieser Übersicht sehen: https://gist.github.com/sadmicrowave/d4fbefc124eb69027d7a3131526e8c06

sadmicrowave
quelle
1
Keine Notwendigkeit zu verwenden [n for n in range(num, 0, -1)], rangeist bereits iterierbar.
Mark Mishyn
0

Eine andere Möglichkeit ist np.proddie unten gezeigte:

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

Fakultät einer positiven ganzen Zahl n, bezeichnet mit n!, Ist das Produkt aller positiven ganzen Zahlen kleiner oder gleich n.

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

Es gibt verschiedene Methoden, um die Fakultät in Python mithilfe der eingebauten Funktion / Bibliothek usw. zu finden. Hier habe ich eine benutzerdefinierte Funktion unter Bezugnahme auf die grundlegende Definition der Fakultät erstellt.

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

print(factorial(4))

Wir können die Fakultätsfunktion auch mithilfe der recursiveunten gezeigten Technik implementieren . Diese Methode ist jedoch nur für kleine ganzzahlige Werte effizient. Da bei der Rekursion die Funktion wiederholt aufgerufen wird und einen Speicherplatz benötigt, um den Stapel zu verwalten, ist dies kein effizienter oder optimierter Ansatz für große ganzzahlige Werte, um die Fakultät zu finden.

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

print(factorial(4))
Usman
quelle
0
def factorial(n):
mul = 1
for i in range( 1, n + 1):
    mul *= i
print(factorial(6))
Jitendra Bhalothia
quelle
Eine weitere Frage ist, was dies zu den anderen 17 Antworten hinzufügt.
pppery
Diese Antwort ist ein Duplikat dieser vorhandenen Antwort: stackoverflow.com/a/5136481
karel
0

Im folgenden Code gebe ich die Zahl ein, deren Fakultät ich berechnen möchte. Danach multipliziere ich die -> Zahl, deren Fakultät wir berechnen möchten, mit Zahlen ab 1,2, ...., (Zahl, deren Fakultät Ich möchte -1) berechnen

    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
quelle