Pythonの階乗の関数


回答:


191

最も簡単な方法は使用することですmath.factorial(Python 2.6以降で利用可能):

import math
math.factorial(1000)

あなたがそれを自分で書きたい/持っているなら、あなたは反復的なアプローチを使うことができます:

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

または再帰的アプローチ:

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

ことを注意階乗関数を使用すると、また、そのチェックする必要がありますので、正の整数だけのために定義されn >= 0、それをisinstance(n, int)。そうでない場合はValueErrorTypeErrorそれぞれa またはaをレイズします。math.factorialこれはあなたの代わりになります。


2
関数factorial内での使用方法がわかりませんfactorial。現在定義している関数内で同じ関数をどのように使用できますか?私はPythonが初めてなので、理解しようとしています。
J82 2014年

8
@ J82:ここで使用される概念は再帰と呼ばれます(en.wikipedia.org/wiki/Recursion_(computer_science))-自分自身を呼び出す関数は完全にうまく機能し、多くの場合便利です。
シュナーダー2014年

Pythonの再帰制限大きくしない限り、再帰関数はRecursionError998を超える任意の数に対してを上げfactorial(999)ます(試行)
Boris

114

Python 2.6以降では、次のことを試してください。

import math
math.factorial(n)

Python 3.9以降ではfloat、この関数にa を渡すとが発生しDeprecationWarningます。これを行う場合はnint明示的にに変換する必要がありますmath.factorial(int(n))。これにより、小数点以下はすべて破棄されるため、それを確認することができますn.is_integer()
Boris

25

これは非常に古いスレッドなので、実際には必要ありません。しかし、ここで行ったのは、whileループを使用して整数の階乗を計算する別の方法です。

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

4
factorial(-1)は1を返し、ValueErrorなどを発生させます。
f.rodrigues 2015年

この関数は、小数の後の数値を含む浮動小数点数を渡すと、誤った結果を生成します。
ボリス

この関数を使用して、最初の4つの整数の階乗を出力します。でnum = num * n行の位置を入れ替えてn = n - 1これを実行すると 、for i in range(1, 5): print('Factorial of', i, 'is', factorial(i))Factorialごとに出力は0になりnum = num * nます。理由を最初に考える必要がある理由を知りたいのですが。ありがとう!!

18

既存のソリューション

最短かつおそらく最速のソリューションは次のとおりです。

from math import factorial
print factorial(1000)

自分で作る

独自のソリューションを構築することもできます。通常、2つのアプローチがあります。私に一番合うのは:

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

print factorial(1000)

(結果がになるとき、それはより大きな数でも機能しますlong

同じことを達成する2つ目の方法は次のとおりです。

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

print factorial(1000)


5

Python2.5以前を使用している場合は、

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

新しいPythonの場合、ここの他の答えで与えられているように数学モジュールに階乗があります


これはPython 2のみの回答で、reducePython 3から削除されました
Boris

@ Boris、Python3で追加する必要があるのはfrom functools import reduce
John La Rooy

理由により削除されました。artima.com/ weblogs / viewpost.jsp?thread
Boris


4

for-ループを使用して、から逆方向にカウントしnます:

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

3

パフォーマンス上の理由から、再帰は使用しないでください。それは悲惨なことでしょう。

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

実行結果を確認する

cProfile.run('fact(126000)')

4 function calls in 5.164 seconds

スタックの使用は(再帰呼び出しのように)便利ですが、コストがかかります。詳細情報を保存すると、大量のメモリを消費する可能性があります。

スタックが高い場合は、コンピューターが関数呼び出しに関する多くの情報を格納していることを意味します。

このメソッドは、定数のメモリのみを使用します(反復など)。

またはforループを使用する

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

実行結果を確認する

cProfile.run('fact(126000)')

4 function calls in 4.708 seconds

または組み込み関数数学を使用する

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

実行結果を確認する

cProfile.run('fact(126000)')

5 function calls in 0.272 seconds

1
このwhileループは少しきれいに見えます<!-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

これが私の試みです

>>> 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、なんて楽しいことだ
Pedro Rodrigues

1

1行で、高速かつ大きな数でも機能します。

#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

私はこれが答えられたことを知っていますが、これは範囲リストを逆に理解して、範囲を読みやすくし、よりコンパクトにする別の方法です:

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

この要点内でコードの完全バージョンを確認できます:https : //gist.github.com/sadmicrowave/d4fbefc124eb69027d7a3131526e8c06


1
使用する必要はありません[n for n in range(num, 0, -1)]rangeすでに反復可能ではありません。
マークミシン

0

それを行う別の方法は、np.prod以下に示すように使用することです:

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

0

階乗n!で表される正の整数nのは、n以下のすべての正の整数の積です。

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

組み込み関数/ライブラリなどを使用してPythonで階乗を見つける方法はいくつかあります。ここでは、階乗の基本的な定義を参照してユーザー定義関数を作成しました。

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

print(factorial(4))

recursive以下に示す手法を使用して階乗関数を実装することもできます。ただし、この方法は小さな整数値に対してのみ効率的です。再帰では、関数は繰り返し呼び出され、スタックを維持するためにメモリ空間を必要とします。これは、大きな整数値が階乗を見つけるための効率的または最適化されたアプローチではありません。

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

print(factorial(4))


0

以下のコードでは、階乗を計算したい数値を入力しています。その後、階乗を計算したい->数を1,2、....、(階乗の数値-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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.