階乗の実装 & ライブラリ【Python】

pythonの階乗のアイキャッチPython

階乗の実装

for文

階乗の実装と一言に言っても、いろんなやり方があります

一番最初に思いつくのが、for文を使った方法ではないでしょうか?

n = 3
ans = 1

for i in range(2, n+1):
    ans *= i

print(ans)

はい、めちゃくちゃ簡単です

再帰

ここで再帰関数を使う方法を思いついたあなたは、もしやプログラミング上級者ですね?

しかし再帰関数には再帰の回数に上限があるのです
デフォルトではおそらく1000回に設定されているのではないでしょうか

以下のコードで確認できます

import sys
print(sys.getrecursionlimit())
# 1000

つまり再帰を使った場合では1001!以上は計算できません
のでできる限り、for文を使った再帰を実装するのが望ましいでしょう

ちなみにコードはこんな感じ

def factorial(x):
    if x==0:
        return 1
    return x * factorial(x-1)

print(factorial(3))
# 6
print(factorial(1001))
# RecursionError: maximum recursion depth exceeded in comparison

ライブラリ

math.factorial(x)

単に階乗を返してくれる関数です
xが負であったり、整数でない時はエラーが返ってきます

import math

print(math.factorial(10))
# 3628800
print(math.factorial(-3))
# ValueError: factorial() not defined for negative values
print(math.factorial(5.5))
# ValueError: factorial() only accepts integral values

scipy.special.factorial(x) numpy配列を扱える

math.factorialなどでも階乗は十分計算できますが、やはり数字を扱うライブラリではnumpyがデファクトスタンダードになっている(ような気がする)ので、numpy配列を扱いところです

そういう時にはscipy.special.factorial()を使いましょう

numpy配列を扱えるし、一度にまとめて階乗を計算できるので効率的です

import math
import numpy as np
import scipy.special

x = np.array([1,2,3,4])

print(scipy.special.factorial(x))
# [ 1.  2.  6. 24.]
print(math.factorial(x))
# TypeError: only size-1 arrays can be converted to Python scalars

豆知識

他にも階乗を計算する関数として、numpy.math.factorial , scipy.math.factorialもありますが、これらはmath.factorialのエイリアスですので、どれを使ってもあまり変わらないと思います

import math
import numpy
import scipy

print(math.factorial == numpy.math.factorial)
# True
print(math.factorial == scipy.math.factorial)
# True

参考

https://codehero.jp/python/21753841/factorial-in-numpy-and-scipy

コメント