閉じる

【Python】randomで乱数生成入門:整数・小数・リストシャッフルを一気に解説

Pythonでランダムな値を扱えるようになると、ゲームの作成、テストデータの生成、シミュレーションなど、できることが一気に広がります。

本記事では、標準ライブラリのrandomモジュールを使って、整数・小数の乱数生成から、リストのシャッフルや抽選の方法までを、丁寧にステップを追って解説します。

実行しながら学べるよう、すべての機能にサンプルコードを用意しています。

Pythonのrandomモジュールとは

randomモジュールでできることと基本的な使い方

randomモジュールは、Python標準ライブラリに含まれる「乱数を扱うための道具箱」です。

外部ライブラリをインストールする必要はなく、インポートするだけですぐに使えます。

というように、乱数に関連した基本的な処理は一通り揃っています。

randomモジュールのインポートと基本形

Pythonでrandomモジュールを使うためには、最初にimport randomを記述します。

最も基本的な使い方を、簡単なサンプルで確認してみましょう。

Python
import random  # randomモジュールをインポート

# 0以上1未満のランダムな小数を1つ生成
value = random.random()

print("0以上1未満の乱数:", value)
実行結果
0以上1未満の乱数: 0.7324455121969435

このように、インポートしてからrandom.関数名という形で呼び出すのが基本の使い方です。

なお、randomモジュールのよく使う関数には、次のようなものがあります。

分類関数名役割の概要
整数乱数randint(a, b)a以上b以下の整数からランダムに1つ取得する
整数乱数randrange(start, stop, step)rangeのように、ステップ付きで整数乱数を生成する
小数乱数random()0以上1未満の小数乱数を生成する
小数乱数uniform(a, b)指定した範囲[a, b]内の小数乱数を生成する
リスト操作shuffle(x)リストxの要素をランダムに並び替える(破壊的)
リスト操作choice(seq)シーケンスからランダムに1要素を取得する
リスト操作sample(population, k)重複なしでk個の要素をランダム抽出する

この記事では、これらの関数を1つずつ具体的に解説していきます。

擬似乱数の仕組みと乱数の再現性

randomモジュールが生成するのは「擬似」乱数です。

完全に予測不可能な真の乱数ではなく、ある規則に基づいて計算された値ですが、人間から見ると十分ランダムに見えるように設計されています。

擬似乱数とは何か

擬似乱数は、内部的にはある「状態」から数学的な計算によって次の値を決めていく仕組みです。

この状態はシード値(seed)と呼ばれる初期値からスタートします。

同じシード値からスタートすると、randomモジュールは同じ順番の乱数列を再現します

この性質は、デバッグや実験の再現にとても便利です。

seed関数で乱数の再現性を確保する

Pythonではrandom.seed()を使うことで、シード値を自分で指定できます。

これにより、プログラムを何度実行しても同じ乱数列を得ることができます。

Python
import random

# シード値を設定(42は任意の整数)
random.seed(42)

print("1回目:", random.random())
print("2回目:", random.random())
print("3回目:", random.random())
実行結果
1回目: 0.6394267984578837
2回目: 0.025010755222666936
3回目: 0.27502931836911926

同じコードを再実行すると、毎回まったく同じ出力が得られます。

テストコードやシミュレーションで「毎回同じ結果を再現したい」ときは、seedを固定するのが定番です。

一方で、ゲームなどで毎回違う結果にしたい場合は、通常seed()を明示的に呼ばずに使います。

その場合、Pythonは自動的に現在時刻などを元にしたシード値を内部で設定します。

randomで整数の乱数を生成する

整数の乱数は、サイコロの目のシミュレーションや、インデックスのランダム選択など、さまざまな場面で使います。

ここではrandintrandrangeという2つの関数を中心に解説します。

randintで指定範囲の整数乱数を取得する

randint(a, b)は、「a以上b以下」の整数をランダムに1つ返す関数です。

両端の値を含むことが大きな特徴です。

randintの基本的な使い方

Python
import random

# 1以上6以下の整数をランダムに取得(サイコロのイメージ)
dice = random.randint(1, 6)

print("サイコロの目:", dice)
実行結果
サイコロの目: 4

この例では、1〜6のどれかの整数が1つランダムに選ばれます。

randint(a, b)は、両端を含む点に注意してください

たとえば、0〜9のランダムな整数が欲しいときはrandom.randint(0, 9)と書きます。

複数回の乱数を取得して分布を確認する

乱数がどの程度バラついているかを、簡単なサンプルで確認してみましょう。

Python
import random
from collections import Counter

random.seed(0)  # 再現性のためシード固定

results = []
for _ in range(1000):
    value = random.randint(1, 6)  # 1〜6の乱数
    results.append(value)

counter = Counter(results)

print("各目の出現回数:")
for eye in range(1, 6 + 1):
    print(f"{eye}: {counter[eye]}回")
実行結果
各目の出現回数:
1: 154回
2: 167回
3: 185回
4: 164回
5: 155回
6: 175回

出現回数は完全に均等ではありませんが、おおよそ同じくらいになっていることが分かります。

randrangeでステップ付きの整数乱数を生成する

randrangeは、整数の範囲に加えて「刻み幅(step)」まで指定できる関数です。

挙動はrange()関数によく似ています。

randrangeの基本形

randrangeの典型的な呼び出し方は次の通りです。

  • random.randrange(stop)
    0以上stop未満の整数をランダムに返す
  • random.randrange(start, stop)
    start以上stop未満の整数をランダムに返す
  • random.randrange(start, stop, step)
    start, start+step, ...のうちstop未満の値からランダムに返す
Python
import random

# 0以上10未満の整数からランダムに1つ
value1 = random.randrange(10)

# 5以上10未満の整数からランダムに1つ
value2 = random.randrange(5, 10)

# 0以上20未満の偶数(0, 2, 4, ..., 18)からランダムに1つ
value3 = random.randrange(0, 20, 2)

print("0〜9のどれか:", value1)
print("5〜9のどれか:", value2)
print("0〜18の偶数のどれか:", value3)
実行結果
0〜9のどれか: 3
5〜9のどれか: 9
0〜18の偶数のどれか: 12

randrangeは「上限値を含まない」点に注意が必要です

randrange(10)は0〜9までの値しか返さず、10は決して返しません。

randintとrandrangeの違いと使い分け

乱数の整数を生成する関数はrandintrandrangeの2種類があり、最初は迷いやすいところです。

関数範囲の指定方法上限値は含むかステップ指定
randint(a, b)a以上b以下含む不可
randrange(start, stop, step)start以上stop未満含まない可能

「両端を含むシンプルな範囲」ならrandint、rangeと同じ感覚で条件を指定したいときはrandrangeというように使い分けると分かりやすいです。

整数乱数のよくある使い方

整数乱数は、身近なシーンで多用されます。

いくつかの典型的な例を挙げます。

サイコロやくじ引きのシミュレーション

Python
import random

def roll_dice():
    """6面サイコロを1回振って目を返す関数"""
    return random.randint(1, 6)

# サイコロを10回振る
for i in range(10):
    print(f"{i+1}回目の目:", roll_dice())
実行結果
1回目の目: 2
2回目の目: 6
3回目の目: 1
4回目の目: 3
5回目の目: 3
6回目の目: 5
7回目の目: 4
8回目の目: 2
9回目の目: 6
10回目の目: 1

ランダムなインデックスの選択

リストからランダムな要素を選びたいとき、後述するchoice()を使う方法もありますが、整数乱数を使ってインデックスを選ぶこともできます。

Python
import random

fruits = ["apple", "banana", "orange", "grape"]

# 0〜len(fruits)-1の範囲でインデックスをランダムに取得
idx = random.randint(0, len(fruits) - 1)

print("選ばれたフルーツ:", fruits[idx])
実行結果
選ばれたフルーツ: orange

インデックスの考え方に慣れておくと、リスト操作全般の理解にもつながります。

randomで小数(浮動小数点)の乱数を生成する

小数の乱数は、確率ベースの処理や、連続値を扱うシミュレーションなどで頻繁に使われます。

ここではrandom()uniform()を中心に解説します。

randomで0以上1未満の小数乱数を得る

random.random()は、0以上1未満の小数(浮動小数点)の乱数を返す関数です。

もっとも基本的な小数乱数の生成方法です。

random()の基本的な使い方

Python
import random

value = random.random()

print("0以上1未満の小数乱数:", value)
print("型:", type(value))
実行結果
0以上1未満の小数乱数: 0.26353217023557313
型: <class 'float'>

返ってきた値はfloat型であり、0.0以上1.0未満のどこかの値になります。

得られた乱数を別の範囲にスケーリングする

random()で得た値は0〜1の範囲ですが、これを自分の好きな範囲に変換することもできます。

たとえば、0〜10の小数乱数が欲しい場合は、以下のように計算します。

Python
import random

x = random.random()       # 0.0 <= x < 1.0
y = x * 10                # 0.0 <= y < 10.0

print("0〜1の乱数:", x)
print("0〜10の乱数:", y)
実行結果
0〜1の乱数: 0.08718667752263232
0〜10の乱数: 0.8718667752263232

また、a〜bまでの範囲にしたい場合は、次のように一般化できます。

a + (b - a) * random.random()

このように、random()は「基準となる0〜1の乱数」として、他の範囲に変換するためにも利用されます。

uniformで任意の範囲の小数乱数を生成する

uniform(a, b)は、指定した範囲[a, b]の小数乱数を直接生成する関数です。

先ほど説明したようなスケーリング計算を、自動でやってくれるイメージです。

uniformの基本的な使い方

Python
import random

# -1.0以上1.0以下の小数乱数
value1 = random.uniform(-1.0, 1.0)

# 10.0以上20.0以下の小数乱数
value2 = random.uniform(10.0, 20.0)

print("[-1.0, 1.0]の乱数:", value1)
print("[10.0, 20.0]の乱数:", value2)
実行結果
[-1.0, 1.0]の乱数: -0.4465738876063467
[10.0, 20.0]の乱数: 17.691102536213483

uniformは指定した両端a, bを含む範囲から値を返します

ただし浮動小数点の性質上、端の値を正確に取ることは実際にはほとんどありません。

小数乱数の応用例

小数乱数は、単にランダムな値を得るだけでなく、確率を使った分岐や、ノイズの付与などに広く用いられます。

確率で処理を分岐させる

たとえば「30%の確率で成功、それ以外は失敗」といった処理は、小数乱数で簡潔に書くことができます。

Python
import random

def is_success(probability: float) -> bool:
    """
    指定した確率(probability)でTrueを返す関数。
    probabilityは0.0〜1.0の範囲を想定(0.3なら30%)。
    """
    r = random.random()  # 0.0 <= r < 1.0
    return r < probability

success_count = 0
trial = 1000

for _ in range(trial):
    if is_success(0.3):  # 30%の確率
        success_count += 1

print(f"成功回数: {success_count} / {trial}")
print(f"成功率(概算): {success_count / trial:.2f}")
実行結果
成功回数: 312 / 1000
成功率(概算): 0.31

ここでは、random()で得た値と、閾値となる確率を比較することで、確率的な分岐を実現しています。

数値データにランダムなノイズを加える

シミュレーションやグラフ描画で、データに少しバラつきを持たせたい場合にも、小数乱数は便利です。

Python
import random

base_value = 100.0  # 基本となる値
noisy_values = []

for _ in range(10):
    # -5.0〜5.0の範囲で乱数ノイズを生成
    noise = random.uniform(-5.0, 5.0)
    noisy_values.append(base_value + noise)

print("ノイズ付きデータ:")
for v in noisy_values:
    print(f"{v:.2f}")
実行結果
ノイズ付きデータ:
97.41
97.86
98.36
102.52
104.06
98.09
98.39
95.83
103.99
95.36

uniformを使えば「基準値±いくつ」といったノイズを簡単に実現できます

リストをシャッフル・抽選する乱数処理

randomモジュールには、リストなどのシーケンスを直接扱う乱数関数も用意されています。

ここではshufflechoicesampleという3つの重要な関数を解説します。

shuffleでリストをランダムシャッフルする

shuffle(x)は、リストxの要素順をランダムに並べ替える関数です。

元のリスト自体を書き換える(破壊的変更)点がポイントです。

shuffleの基本的な使い方

Python
import random

cards = ["A", "2", "3", "4", "5", "6", "7",
         "8", "9", "10", "J", "Q", "K"]

print("シャッフル前:", cards)

random.shuffle(cards)  # リスト自体をシャッフル(戻り値はNone)

print("シャッフル後:", cards)
実行結果
シャッフル前: ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
シャッフル後: ['3', '7', 'K', 'A', '5', '9', 'Q', '10', '8', '4', '2', '6', 'J']

注意したいのはshuffleは新しいリストを返さず、引数として渡したリストを直接書き換える点です。

戻り値はNoneなので、次のように書くと意図通りには動きません。

Python
import random

numbers = [1, 2, 3]

# これは間違い(戻り値はNone)
shuffled = random.shuffle(numbers)

print("shuffled:", shuffled)      # None
print("numbers:", numbers)        # [2, 1, 3] など(こちらがシャッフルされたリスト)
実行結果
shuffled: None
numbers: [3, 1, 2]

shuffleの結果を変数に代入したくなりますが、代入してはいけません

シャッフルされたリストを使いたいときは、元のリスト変数自体を参照します。

choiceでリストからランダムに1要素を選ぶ

choice(seq)は、シーケンス(リストやタプルなど)からランダムに1要素を選んで返す関数です。

元のシーケンスは変更されません。

choiceの基本的な使い方

Python
import random

members = ["Alice", "Bob", "Charlie", "Diana"]

winner = random.choice(members)

print("メンバー一覧:", members)
print("当選者:", winner)
実行結果
メンバー一覧: ['Alice', 'Bob', 'Charlie', 'Diana']
当選者: Charlie

choiceは「1つだけ選びたい」ときの最適な関数です。

インデックスを乱数で選んでから要素を取るよりも、コードが短く分かりやすくなります。

文字列からランダムな文字を選ぶ

choiceはリストだけでなく、タプルや文字列など、シーケンス型に対しても使えます。

Python
import random

alphabet = "abcdefghijklmnopqrstuvwxyz"

ch = random.choice(alphabet)

print("選ばれた文字:", ch)
実行結果
選ばれた文字: q

このように、「シーケンスからランダムに1つ」なら、とりあえずchoiceと覚えておくと役立ちます。

sampleで重複なしのランダム抽選を行う

sample(population, k)は、母集団(population)から重複なしでk個の要素をランダム抽出する関数です。

抽出された要素は新しいリストとして返されます。

sampleの基本的な使い方

Python
import random

numbers = list(range(1, 11))  # 1〜10

# numbersから重複なしで3つの値をランダムに抽出
picked = random.sample(numbers, 3)

print("元のリスト:", numbers)
print("抽選結果:", picked)
実行結果
元のリスト: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
抽選結果: [4, 9, 2]

sampleは元のリストを変更しないため、元データを残したまま何度も抽選を行いたい場合に向いています。

抽選人数を超えるkは指定できない

sampleは「重複なし」で抽選するため、kに母集団より大きな値を指定することはできません。

その場合はValueErrorが発生します。

Python
import random

numbers = [1, 2, 3]

# 母集団3個しかないのに、4個抽選しようとするとエラー
picked = random.sample(numbers, 4)
実行結果
Traceback (most recent call last):
  ...
ValueError: Sample larger than population or is negative

「重複を許して抽選したい」場合はsampleではなく、choiceを複数回呼ぶ必要がある点に注意してください。

抽選処理の具体例

例えば「10人の中から3人を当選者として選ぶ」という処理は、次のように書けます。

Python
import random

members = ["Aさん", "Bさん", "Cさん", "Dさん", "Eさん",
           "Fさん", "Gさん", "Hさん", "Iさん", "Jさん"]

winners = random.sample(members, 3)

print("当選者:")
for w in winners:
    print("-", w)
実行結果
当選者:
- Cさん
- Hさん
- Aさん

sampleは「抽選」「くじ引き」「座席決め」など、現実世界でもよくあるシチュエーションをコードに落とし込みたいときに非常に役立ちます

まとめ

Pythonのrandomモジュールを使うことで、整数・小数の乱数生成から、リストのシャッフル、抽選処理まで、一通りの「ランダムな処理」をシンプルなコードで実現できます。

整数にはrandintrandrange、小数にはrandomuniform、リスト処理にはshufflechoicesampleと、それぞれ役割がはっきり分かれています。

またseedによる乱数の再現性も重要なポイントです。

本記事のサンプルを実行しながら、用途ごとに最適な関数を選べるようになれば、実践的なPythonプログラミングの幅が大きく広がります。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!