Pythonで再帰関数を作成するにはどうすればよいですか?
4 に答える
あなたが「再帰的」を意味したのかどうか疑問に思います。階乗関数を計算するための再帰関数の簡単な例を次に示します。
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
再帰的アルゴリズムの2つの重要な要素は次のとおりです。
- 終了条件:
n == 0
- 関数が毎回小さい数で自分自身を呼び出す削減ステップ:
factorial(n - 1)
Python での再帰は、他の言語での再帰と同じように機能し、再帰構造がそれ自体で定義されています。
たとえば、再帰クラスはバイナリ ツリー (または任意のツリー) である可能性があります。
class tree():
def __init__(self):
'''Initialise the tree'''
self.Data = None
self.Count = 0
self.LeftSubtree = None
self.RightSubtree = None
def Insert(self, data):
'''Add an item of data to the tree'''
if self.Data == None:
self.Data = data
self.Count += 1
elif data < self.Data:
if self.LeftSubtree == None:
# tree is a recurive class definition
self.LeftSubtree = tree()
# Insert is a recursive function
self.LeftSubtree.Insert(data)
elif data == self.Data:
self.Count += 1
elif data > self.Data:
if self.RightSubtree == None:
self.RightSubtree = tree()
self.RightSubtree.Insert(data)
if __name__ == '__main__':
T = tree()
# The root node
T.Insert('b')
# Will be put into the left subtree
T.Insert('a')
# Will be put into the right subtree
T.Insert('c')
すでに述べたように、再帰構造には終了条件が必要です。このクラスでは、新しい要素が追加された場合にのみ再帰を実行し、1 回余分に実行するだけなので、それほど明白ではありません。
また、注目に値するのは、コンピューターのすべてのメモリを吸収することを避けるために、デフォルトで python が使用できる再帰の深さに制限があることです。私のコンピューターでは、これは 1000 です。これがハードウェアなどによって変わるかどうかはわかりません。
import sys
sys.getrecursionlimit()
そしてそれを設定するには:
import sys #(if you haven't already)
sys.setrecursionlimit()
編集: 私のバイナリ ツリーがこれまでで最も効率的な設計であることを保証することはできません。誰かがそれを改善できるなら、私はその方法を聞いてうれしいです
ビルドしたいとします:u(n + 1)= f(u(n))with u(0)= u0
1つの解決策は、単純な再帰関数を定義することです。
u0 = ...
def f(x):
...
def u(n):
if n==0: return u0
return f(u(n-1))
残念ながら、uの高い値を計算したい場合は、スタックオーバーフローエラーが発生します。
別の解決策は単純なループです。
def u(n):
ux = u0
for i in xrange(n):
ux=f(ux)
return ux
ただし、nの異なる値に対してuの複数の値が必要な場合、これは最適ではありません。すべての値を配列にキャッシュすることはできますが、メモリ不足エラーが発生する可能性があります。代わりにジェネレーターを使用することをお勧めします。
def u(n):
ux = u0
for i in xrange(n):
ux=f(ux)
yield ux
for val in u(1000):
print val
他にもたくさんの選択肢がありますが、これらが主な選択肢だと思います。
再帰関数の例:
def recursive(string, num):
print "#%s - %s" % (string, num)
recursive(string, num+1)
次のように実行します。
recursive("Hello world", 0)