再帰処理
前回、Pythonのmatplotlibでグラフの中に拡大図のような小さなグラフを表示する方法:inset_axes編を紹介しました。
今回は再帰処理を使って0を含まないランダムな数値のリストを作成する方法を紹介します。
random.random()では「0以上1未満のランダムな小数」を作成しますが、0が出る場合もわずかながら確率的に含まれます。
またrandom.uniform()で正負をまたがる範囲とした場合、こちらもわずかながら0が出る場合が存在します。
しかしその後の数式上、これらの関数で取得した値で割り算をしたいとなると0が許されません。
しかもランダムな値のリストを作成しておいてから割り算のような計算に用いる場合、リストに0が含まれているとエラーが発生してしまいます。
なかなかレアなケースかもしれないので、イメージできないかもしれません。
ただ私自身「ランダムな数値のリスト」を作りつつ、そのリストの中に「0が許されない」場合というのが存在したので、そのようなリストの作り方を考えてみたというのが今回のお話です。
それでは始めていきましょう。
とりあえずランダムなリストを作ってみる
とりあえずランダムなリストを作ってみて、どういう状況かご覧いただきましょう。
今回は0が出やすい例として「random.randrange関数」を使って試してみます。
import random
x = [random.randrange(10) for _ in range(10)]
print(x)
実行結果
[3, 2, 0, 2, 0, 1, 2, 1, 2, 0]
random.randrange関数なので、「random.randrange(1, 10)」と範囲指定をすれば0が出ないのですが、今回はあくまでも解説用ということでご容赦ください。
これをfor文とif文を使って0だった場合は再度random.randrange関数を使って、ランダムな数値を取得してみるとこうなります。
import random
x = []
for _ in range(10):
val = random.randrange(10)
if val != 0:
x.append(val)
else:
val = random.randrange(10)
x.append(val)
print(x)
実行結果
[8, 8, 2, 6, 4, 0, 1, 9, 3, 7]
こうすれば「0」がでる確率は減るのですが、それでも「0」は出てしまいます。
かといって何度もif文で条件分岐を繰り返すというのは面倒です。
ということで再帰処理を使ってプログラムを書いてみました。
再帰処理を使って0を含まないランダムな数値のリストを取得する方法
ということで作成してみたのがこちらです。
import random
x = []
def non_zero_random(n):
if n == 0:
return
val = random.randrange(10)
if val == 0:
non_zero_random(n)
else:
x.append(val)
non_zero_random(n-1)
non_zero_random(10)
print(x)
実行結果
[4, 2, 9, 6, 2, 4, 5, 6, 1, 9]
最初に再帰処理の関数からアクセスできる形でリストを作成します(x = [])。
今回の再帰処理の関数「non_zero_random(n)」(nは取得する数値の数)では、まず「val = random.randrange(10)」でランダムな数値を取得します。
実際は「random.random関数」や「random.uniform関数」に変更して使ってください。
そして取得した値valが0だった場合、何もせずに再度「non_zero_random関数」を実行します。
取得した値valが0ではなかった場合、リストxに値を追加して、「n-1」で再度「non_zero_random関数」を実行します。
そして「n-1が0」になったら、「non_zero_random関数」は終了します。
このように「0だったら何もしない」、「0以外ならリストに追加する」を繰り返して、0以外のランダムな数値のリストを作成しているというわけです。
再帰処理は考えるのがなかなか難しいですが、やはり使えるとやれることが広がるので覚えておくに越したことはなさそうです。
ということでよかったらこちらの記事もどうぞ。
次回は再帰処理を大量に行った場合に出る「RecursionError: maximum recursion depth exceeded while calling a Python object」の対処法を紹介します。
ではでは今回はこんな感じで。
コメント