Pythonでランダムな小数・整数を生成するrandom, randrange, randintなど

Modified: | Tags: Python, 数値

Python標準ライブラリのrandomモジュールの関数random()uniform(), randrange(), randint()などを使うと、乱数(ランダムな浮動小数点数floatや整数int)を生成できる。

なお、randomモジュールをセキュリティ用途で使用するのは非推奨。

警告: このモジュールの擬似乱数生成器をセキュリティ目的に使用してはいけません。セキュリティや暗号学的な用途については secrets モジュールを参照してください。 random --- 擬似乱数を生成する — Python 3.11.3 ドキュメント

そのような用途にはsecretsモジュールを使う。

リストの要素をランダムに抽出したり、並べ替えたりする方法は以下の記事を参照。

また、NumPyでの乱数生成については以下の記事を参照。

random.random() (0.0以上1.0未満の浮動小数点数)

randomモジュールの関数random()は0.0以上1.0未満の浮動小数点数float型の乱数を生成する。

import random

print(random.random())
# 0.4496839011176701

random.uniform()(任意の範囲の浮動小数点数)

randomモジュールの関数uniform(a, b)は任意の範囲(a <= n <= bまたはb <= n <= a)の浮動小数点数float型の乱数を生成する。

import random

print(random.uniform(100, 200))
# 175.26585048238275

2つの引数はどちらが大きくてもOK。等しい値の場合は当然ながらその値しか返さない。返り値は常にfloat

print(random.uniform(100, -100))
# -27.82338731501028

print(random.uniform(100, 100))
# 100.0

引数はfloatでも指定できる。

print(random.uniform(1.234, 5.637))
# 2.606743596829249

bの値が範囲に含まれるかはドキュメントの通り、a + (b-a) * random.random()の丸めに依存。

端点の値 b が範囲に含まれるかどうかは、等式 a + (b-a) * random() における浮動小数点の丸めに依存します。
random.uniform() — Python 3.11.3 ドキュメント

正規分布やガウス分布などに従う乱数の生成

上述のrandom(), uniform()は一様分布の乱数を生成するが、以下のような分布に従う浮動小数点数を生成する関数も用意されている。

  • ベータ分布: random.betavariate()
  • 指数分布: random.expovariate()
  • ガンマ分布: random.gammavariate()
  • ガウス分布: random.gauss()
  • 対数正規分布: random.lognormvariate()
  • 正規分布: random.normalvariate()
  • フォン・ミーゼス分布: random.vonmisesvariate()
  • パレート分布: random.paretovariate()
  • ワイブル分布: random.weibullvariate()

それぞれの分布のパラメータを引数で指定するようになっている。詳細は公式ドキュメントを参照。

random.randrange() (任意の範囲・ステップの整数)

randomモジュールの関数randrange(start, stop, step)は、range(start, stop, step)の要素からランダムに選ばれた要素(整数int型)を返す。

range()と同じく、引数start, stepは省略可能。省略した場合はstart=0, step=1となる。

import random

print(list(range(10)))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(random.randrange(10))
# 5

引数stepを設定すると、偶数または奇数のランダム整数を生成したり、3の倍数のランダム整数を生成したりすることができる。

例えば、startが偶数でstep=2だと、範囲内の偶数の整数のみがランダムに取得できる。

print(list(range(10, 20, 2)))
# [10, 12, 14, 16, 18]

print(random.randrange(10, 20, 2))
# 18

random.randint()(任意の範囲の整数)

randomモジュールの関数randint(a, b)a <= n <= bのランダムな整数intを返す。randrange(a, b + 1)と等価。bの値も範囲に含むので注意。

print(random.randint(50, 100))
# print(random.randrange(50, 101))
# 74

ランダムな数値を要素とするリストの生成

ここでは標準ライブラリのrandomモジュールを使ってランダムな数値を要素とするリストを生成する方法について説明する。

NumPyを使うと多次元配列の生成も簡単なので、NumPyが使える環境であれば以下の記事も参照されたい。

浮動小数点数floatの乱数のリスト

浮動小数点数の乱数を要素とするリストを生成するには、random()uniform()関数などとリスト内包表記を組み合わせる。

import random

print([random.random() for i in range(5)])
# [0.5518201298350598, 0.3476911314933616, 0.8463426180468342, 0.8949046353303931, 0.40822657702632625]

上の例ではrange()を使っているが、所望の要素数であればリストやタプルでも可能。リスト内包表記についての詳細は以下の記事を参照。

整数intの乱数のリスト

整数の乱数を要素とするリストを生成する場合、上述のrandrange()randint()をリスト内包表記と組み合わせると、値が重複する可能性がある。

print([random.randint(0, 10) for i in range(5)])
# [8, 5, 7, 10, 7]

重複なしの整数の乱数列にしたい場合は、任意の範囲を指定したrange()の要素をrandom.sample()で抽出(ランダムサンプリング)する。

print(random.sample(range(10), k=5))
# [6, 4, 3, 7, 5]

print(random.sample(range(100, 200, 10), k=5))
# [130, 190, 140, 150, 170]

random.sample()についての詳細は以下の記事を参照。

乱数生成器を初期化(乱数シードを固定)

randomモジュールの関数seed()に任意の整数を与えることで、乱数シードを固定し乱数生成器を初期化できる。

同じシードで初期化した後は常に同じように乱数値が生成される。

random.seed(0)
print(random.random())
# 0.8444218515250481

print(random.random())
# 0.7579544029403025

random.seed(0)
print(random.random())
# 0.8444218515250481

print(random.random())
# 0.7579544029403025

関連カテゴリー

関連記事