再帰処理
前回、多次元のリストやタプルをSet型を使って重複を削除する方法を紹介しました。
今回はTurtleで木を描いたときに使った再帰処理をもう少し勉強して、全組み合わせを作るプログラムを書いてみます。
まずはおさらいからです。
再帰処理とは「プログラム中にそのプログラム自身を呼び出す記述があるプログラム」でした。
ということで例えばこんな感じです。
def count(n):
if n == 0:
return
print(n)
count(n-1)
count(5)
実行結果
5
4
3
2
1
countという関数の中にcountという関数が使われています。
この際注意することは必ず終了条件をif文で書き、returnで終わらせることです。
再帰処理で全組合せを作るプログラムを作成してみる
今回はもう少し再帰処理を使ってみるために、例として2つの数字を入力し、それぞれの値以下の数字を使って、全組合せを作るプログラムを書いてみます。
ちなみに再帰処理を使わないとこんな感じです。
def count(n, m):
for i in range(n, 0, -1):
for j in range(m, 0, -1):
print(i, j)
count(3, 2)
実行結果
3 2
3 1
2 2
2 1
1 2
1 1
それぞれの数字をrange関数でリストに変換し、for文を使って順に取り出すことによって組合せを作成しています。
で再帰処理を使って作ってみたのがこちら。
data = []
def count(n, m):
if n == 0 or m == 0:
return
data.append((n, m))
count(n-1, m)
count(n, m-1)
count(3, 2)
print(data)
print(set(data))
実行結果
[(3, 2), (2, 2), (1, 2), (1, 1), (2, 1), (1, 1), (3, 1), (2, 1), (1, 1)]
{(1, 2), (2, 1), (3, 1), (1, 1), (2, 2), (3, 2)}
解説していくとcount関数には2つの引数nとmが渡されます。
最初に終了条件ですが「if n == 0 or m == 0:」ということでnかmが0になったら終了します。
そしてn、mの数字はタプルとして、dataというリストに格納されます。
ここでなぜタプルにしてあるかというと、前回学んだように二次元目以降はタプルにしておくとその後Set型に変換することで重複を削除できるからです。
次に再帰処理が行われます。
今回の再帰処理は「count(n-1, m)」と「count(n, m-1)」の2種類あります。
これは「count(n-1, m)」が繰り返されて「n-1が0」になった時、この今度は「count(n, m-1)」が繰り返されます。
つまり実行すると「3, 2」、「2, 2」、「1, 2」とnの値が減少していき、n-1が0となったら今度は「1, 1」とmの値が減少します。
次はm-1も0になってしまうため、次は「2, 1」を開始点として「1, 1」が得られます。
ここでn-1もm-1も0になるため「3, 1」を開始点として「2, 1」「1, 1」が出力されるという流れです。
得られた組合せは重複を含んでいるため、Set型にすることで重複を削除しています。
ということで再帰処理を使って全組合せを出力するプログラムができました。
正直、これくらいの処理ではあまり再帰処理のメリットがわかりませんが、前回のTurtleでTreeを描いた時のように再帰処理でないとできないことというのも多いのだと思います。
とりあえずこんな処理があるということだけ覚えておくといいのかなと思います。
次回はtqdmモジュールを使って繰り返し処理の進捗具合をプログレスバーとして表示してみましょう。
ではでは今回はこんな感じで。
コメント