Pythonで疑似乱数を生成する

疑似乱数の生成

Pythonで疑似乱数を生成するには、標準ライブラリのrandomモジュールを利用する。生成したい値が「整数か小数か」「どんな方法で生成するか」により、利用する関数が異なる。また、あくまでも生成するのは「疑似乱数」なので、高いセキュリティが求められるような場合には利用してはいけない(そのような場合はsecretsが用意されている)。

secrets モジュールを使って、パスワードやアカウント認証、セキュリティトークンなどの機密を扱うのに適した、暗号学的に強い乱数を生成することができます。
特に、 random モジュールのデフォルトの擬似乱数よりも secrets を使用するべきです。 random モジュールはモデル化やシミュレーション向けで、セキュリティや暗号学的に設計されてはいません。

なお、当エントリ中では以降「疑似乱数」を単純に「乱数」と表現する。また、NumPyを利用した乱数の生成は今回は触れない。

利用について

処理させる際には下記のようにモジュールのインポートが必要。

>>> import random  

コード

整数用

整数の乱数を取得する場合は、randint()あるいはrandrange()を用いる。randrange()には2パターンの記述方法がある。

  • randrange(stop)
  • randrange(start, stop[, step])

randrange(stop)

https://docs.python.org/ja/3/library/random.html#random.randrange

0<=N<stopである整数Nをランダムで返す。

>>> random.randrange(10)  
2  
>>> random.randrange(10)  
6  
>>> random.randrange(10)  
0  

randrange(start, stop[, step])

https://docs.python.org/ja/3/library/random.html#random.randrange

start <= N < stopである整数Nをランダムで返す。

stepが省略された場合はデフォルトで1が指定される。指定された場合はi >= 0であるiを取って、start + step*i <= N < stopである整数Nをランダムで返す。

>>> random.randrange(1, 10, 2)  
9  
>>> random.randrange(1, 10, 2)  
3  
>>> random.randrange(1, 10, 2)  
5  

randint(a, b)

https://docs.python.org/ja/3/library/random.html#random.randint

a <= N <= bである整数Nを返す。randrange()との違いは指定された第2引数(randintだとb、randrangeではstop)が含まれるか否か。

>>> random.randint(1, 10)  
9  
>>> random.randint(1, 10)  
10  
>>> random.randint(1, 10)  
7  

小数用

random()

https://docs.python.org/ja/3/library/random.html#random.random

ランダムな浮動小数点数を返す。

>>> random.random()  
0.5734157593305601  
>>> random.random()  
0.13033356630303417  
>>> random.random()  
0.6937873743526288  

uniform(a, b)

https://docs.python.org/ja/3/library/random.html#random.uniform

a <= bであればa <= N <= bb < aであればb <= N <= aであるようなランダムな浮動小数点数Nを返す。ちなみに、aまたはbを指定しなかった場合はエラーになる。

>>> random.uniform(0.1, 0.4)  
0.19936745404185774  
>>> random.uniform(0.3, 0.8)  
0.5111372505372868  
>>> random.uniform(0.2, 0.3)  
0.2822244729266813  

その他

これら以外にも下記のような関数がある。

ちなみに

正規分布の別名はガウス分布なので、関数がそれぞれ別に用意されているのを不思議に思っていたのだが、gauss()normalvariate()より少しだけ高速、ということらしい。

また、ポワソン分布などによる乱数生成は標準ライブラリでは実装できないが、Numpy.randomを利用することで実装が可能となる。