Funktion für Factorial in Python


135

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

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.


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)

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

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)


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


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

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)

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

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

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'

@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

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


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))

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))


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.