Python

【Python】乱数の使い方【randomモジュール】

この記事では、Pythonで擬似乱数を生成する方法を解説します。Pythonで乱数を扱うには、標準ライブラリのrandomモジュールを使います。乱数を使うことでジャンケンなどのちょっとした遊びも実装できます。それでは、乱数の使い方を見ていきましょう❗️

ランダムな整数を生成する

ランダムな整数を生成するには、以下のメソッドを使います。

randrange(start,stop,step) range(start, stop, step)の要素から、1つランダムに選んで返します。
randint(a, b) randrange(a, b+1) のエイリアス
getrandbits(k) k個のビット数の範囲から、1つランダムに選んで返します。

randrange(start,stop,step)

range関数で生成した範囲の中から、ランダムに要素を1つ取得できるイメージ。

import random

print(f'range: {list(range(5))}, value: {random.randrange(5)}')
print(f'range: {list(range(3, 8))}, value: {random.randrange(3, 8)}')
print(f'range: {list(range(1, 10, 2))}, value: {random.randrange(1, 10, 2)}')

実行結果

range: [0, 1, 2, 3, 4], value: 1
range: [3, 4, 5, 6, 7], value: 7
range: [1, 3, 5, 7, 9], value: 5

randint(a, b)

randrange(a, b+1)のエイリアス。stepを使わない場合はこちらの方が楽。

print(f'range: {list(range(-5, -1+1))}, value: {random.randint(-5, -1)}')

実行結果

range: [-5, -4, -3, -2, -1], value: -2​

getrandbits(k)

k個のビット数の範囲からランダムに1つ返します。

import random

# 0000 ~ 0011
print(random.getrandbits(2))

# 0000 ~ 1111
print(random.getrandbits(4))

実行結果

3
14

ランダムな実数を生成する

ランダムな整数を生成するには、以下のメソッドを使います。

random() 0.0 ~ 1.0の範囲からランダムに実数を返します
uniform(a, b) a ~ bの範囲内の実数をランダムに返します

random()

0.0 ~ 1.0の範囲からランダムに実数を返します。

import random

print(random.random())

実行結果

0.8743999006747728

uniform(a, b)

a ~ bの範囲内の実数をランダムに返します。a,bどちらが大きくても問題ない。

import random

# uniform(2, 1)でも同じ
print(random.uniform(1, 2))

実行結果

1.474493558179623

小数点以下を丸める

小数を丸めたい場合は、round関数を使います。

import random

print(round(random.random(), 2))

実行結果

0.27

シーケンスの要素をランダムに取得する

整数や実数以外のオブジェクトをランダムに取得するには、シーケンスの要素をランダムに取得することで実現できます。

要素をランダムに取得する

シーケンスの要素をランダムに取得するには、random.choiseメソッドを使います。

random.choice(seq)

choiceメソッドは、引数に指定されたシーケンスの要素をランダムに返します。引数に指定したシーケンスが空の場合は、IndexErrorが発生します。

import random

l = [1, 2, 3, 4, 5]

for i in range(3):
    print(random.choice(l))

# 要素を抜き取っているわけではないので重複もあり得る
print(l)

実行結果

3
1
4
[1, 2, 3, 4, 5]

確率を変更して要素を取得する

確率を変更してシーケンスの要素をランダムに取得したい場合は、random.choisesメソッドを使います。

random.choices(population, weights=None, *, cum_weights=None, k=1)

population引数に指定したシーケンスから、k個の要素をランダムに取得します。

また、重みを渡すことで要素が選ばれる確率を変更することができます。重みはweights引数、またはcum_weights引数にシーケンスを渡すことで指定できます。重みが渡されなかった場合は同じ確率で選択されます。

import random

# ガチャの中身
contents = ('超激レア', '激レア', 'レア')

# 累積的な重み(超激レア=10%, 激レア=20%, レア=70%)
cum_weights = (1, 3, 10)

# 10連ガチャ(k引数で回数を指定しています)
gacha10 = random.choices(contents, cum_weights=cum_weights, k=10)
print(gacha10)

実行結果

['レア', 'レア', '激レア', 'レア', '超激レア', '激レア', '激レア', 'レア', 'レア', 'レア']
  • 重みの長さは、populationに指定したシーケンスと同じにする
  • 相対的な重みは関数内で累積的な重みに変換されるので、最初から累積的な重みを渡すほうが効率が良い

重みの補足

重みには、「相対的な重み」と「累積的な重み」があります。どのように指定すればいいのか、もう少しだけ詳しく見ていきましょう!

相対的な重み

相対的な重みで「10%」「30%」「60%」の確率で要素を取得するには、以下のように指定します。

weights = (10, 30, 60)

確率は「要素の値 / 合計値」で計算されます。上記シーケンスの合計は100なので、10 / 100 = 0.130 / 100 = 0.360 / 100 = 0.6となっています。

なので、以下のような重みは先ほどの重みと同等です。

# 合計 50
weights = (5, 15, 30)
# 合計 10
weights = (1, 3, 6)
累積的な重み

累積的な重みで「10%」「30%」「60%」の確率で要素を取得するには、以下のように指定します。

cum_weights = (1, 4, 10)

確率は「左の要素から増えた値 / 末尾の要素の値」で計算されます。上記シーケンスの末尾の値は10なので、(1 - 0) / 10 = 0.1(4 - 1) / 10 = 0.3(10 - 4) / 10 = 0.6となっている。

なので、以下のような重みは先ほどの重みと同等である。

cum_weights = (5, 20, 50)
cum_weights = (10, 40, 100)

シーケンスの要素をランダムに並び替える

シーケンスの要素をランダムに並び替えるには、shuffle関数を使います。並び替えたシーケンスを返すのではなく、引数に指定されたシーケンスを並び変えます。

import random

# 連番のリスト生成
nums = list(range(1, 6))
print(nums)

# シャッフル
random.shuffle(nums)
print(nums)

実行結果

[1, 2, 3, 4, 5]
[1, 4, 2, 5, 3]

まとめ

この記事では、Pythonの乱数の使い方を簡単に解説しました。

乱数を使うことで何かしら値が必要な時にランダムに値を生成することができます。

randomモジュールには、今回紹介したもの以外にたくさんの関数が定義されています。気になる方は、公式ドキュメントを参照してください。

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

【Python】ジャンケンを実装してみよう!この記事では、Pythonでジャンケンを実装してみます。 ジャンケンについて考える まずは、ジャンケンについて少し整理しておきま...
最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』