階乗の実装
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
コメント