閉じる

Pythonで乱数生成: randomの基本とrandint/choice/shuffle

乱数はゲームの出目やデータのサンプリングなど、初心者から上級者まで幅広い場面で使われます。

本記事ではPython標準ライブラリのrandomモジュールを取り上げ、randintchoiceshuffleの基本を丁寧に解説します。

再現性(シード)や注意点も押さえながら、安全に使える知識を身につけましょう。

Pythonの乱数(random)の基本

Pythonで乱数を扱うときはrandomモジュールを使います。

randomは「疑似乱数」であり、内部状態(シード)に基づいて見かけ上ランダムな値を生成します。

再現可能なテストを行いたい場合はrandom.seed(数値)でシードを固定することができます。

逆に、セキュリティ用途(パスワードやトークン生成)ではrandomを使わずsecretsモジュールを使います。

randomモジュールの読み込みと代表的な関数

最初にモジュールを読み込みます。

ここでは全体像だけを掴み、具体例は後続の章で扱います。

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

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

# 区間[a, b]の整数(両端を含む) 例: 1〜6のどれか
d = random.randint(1, 6)

# シーケンスから1要素をランダムに選ぶ
item = random.choice(["apple", "banana", "cherry"])

# リストの要素順をシャッフル(破壊的)
cards = [1, 2, 3, 4, 5]
random.shuffle(cards)
print(x, d, item, cards)

出力例(実行のたびに異なります):

実行結果
0.234567890123 3 banana [4, 2, 5, 1, 3]

シードと再現性のポイント

テストや学習では結果を固定したいことがよくあります。

random.seed(123)のように設定すると、その後の乱数列が同じになります。

これにより、説明用の実行結果やユニットテストの安定性が保てます。

なお、randomのアルゴリズムは実装依存であり将来的に変更される可能性がありますが、現行のCPythonではMersenne Twisterが用いられています。

本記事で扱う関数の位置づけ

関数名主な用途代表的な引数返り値破壊的変更
randint(a, b)整数の乱数下限a, 上限b(両端含む)intいいえ
choice(seq)シーケンスから1要素選択リスト・タプル・文字列など要素1ついいえ
shuffle(lst)リストをシャッフル変更可能シーケンス(リスト)Noneはい

このあと、それぞれの使い方を具体例で解説します。

randintの使い方(整数の乱数)

指定範囲の整数を1つ生成

randint(a, b)区間[a, b]の両端を含む形で、整数を1つ返します。

最小値と最大値を含むことがポイントです。

Python
import random

# 1〜10の整数を1つ取得
n = random.randint(1, 10)
print(f"1〜10の乱数: {n}")

# マイナスの範囲でもOK (-5〜5)
m = random.randint(-5, 5)
print(f"-5〜5の乱数: {m}")
実行結果
1〜10の乱数: 7
-5〜5の乱数: -2

例外と境界の注意

a > b を渡すと ValueErrorになります。

範囲はa <= 値 <= bの関係を満たします。

範囲は両端を含むことに注意

Pythonのrangeは上端を含みませんが、randintは上端を含みます

これを混同しやすいので注意しましょう。

たとえば、サイコロ(1〜6)はrandom.randint(1, 6)と書きます。

両端が含まれることのイメージを、可能な値の集合で確認します。

Python
# randint(1, 6) の取りうる値は 1,2,3,4,5,6 の6通り
possible = set(range(1, 6 + 1))
print(possible)
実行結果
{1, 2, 3, 4, 5, 6}

サイコロを振る例

実際にサイコロの出目を複数回表示してみます。

Python
import random

def roll_dice(times=5):
    """サイコロ(1〜6)を指定回数振って表示する"""
    for i in range(1, times + 1):
        face = random.randint(1, 6)  # 両端(1と6)を含む
        print(f"{i}回目の出目: {face}")

# 5回振る
roll_dice(5)
実行結果
1回目の出目: 4
2回目の出目: 1
3回目の出目: 6
4回目の出目: 2
5回目の出目: 5

choiceの使い方(リストから1つ選ぶ)

シーケンスからランダムに1件選択

random.choice(seq)シーケンス(リスト・タプル・文字列)から1要素をランダムに返す関数です。

等確率で選ばれます。

Python
import random

colors = ["red", "green", "blue", "yellow"]
picked = random.choice(colors)
print(f"選ばれた色: {picked}")

# 文字列から1文字を選ぶことも可能
ch = random.choice("PYTHON")
print(f"選ばれた文字: {ch}")
実行結果
選ばれた色: green
選ばれた文字: T

空のリストはエラーになる

空のシーケンスは選べないため、IndexErrorが発生します。

事前に長さを確認するか、例外を処理しましょう。

Python
import random

items = []
try:
    random.choice(items)
except IndexError as e:
    print(f"空からは選べません: {e}")
実行結果
空からは選べません: Cannot choose from an empty sequence

少し厳密に言うと、choiceは「インデックスアクセスが可能なシーケンス」を想定しています。

集合(set)のような順序なしコレクションは直接使えないのでlist()などで変換します。

メニューから1つ選ぶ例

ランチメニューから今日の一品を決める例です。

簡単ですが実用的なパターンです。

Python
import random

menu = ["ラーメン", "カレー", "定食", "サンドイッチ", "パスタ"]

today = random.choice(menu)
print(f"今日のランチは: {today}")
実行結果
今日のランチは: 定食

shuffleの使い方(リストを並び替え)

リストをその場でシャッフル(破壊的変更)

random.shuffle(lst)リストの要素順をその場で並び替えます(破壊的変更)

元の順序は失われるため、残しておきたい場合は先にコピーを作ってください。

Python
import random

nums = [1, 2, 3, 4, 5]
print("シャッフル前:", nums)

random.shuffle(nums)  # 破壊的に並び替え
print("シャッフル後:", nums)

# 元の順序を残したい場合
nums2 = [1, 2, 3, 4, 5]
shuffled_copy = nums2[:]  # スライスで浅いコピー
random.shuffle(shuffled_copy)
print("元:", nums2)
print("コピーをシャッフル:", shuffled_copy)
実行結果
シャッフル前: [1, 2, 3, 4, 5]
シャッフル後: [3, 1, 5, 2, 4]
元: [1, 2, 3, 4, 5]
コピーをシャッフル: [2, 5, 1, 3, 4]

戻り値はNoneに注意

shuffleの戻り値はNoneです。

関数が結果を返すのではなく、引数のリスト自体が書き換えられる点に注意しましょう。

Python
import random

values = [10, 20, 30, 40]
result = random.shuffle(values)

print("戻り値:", result)       # None
print("values:", values)      # 並び替え済み
実行結果
戻り値: None
values: [30, 10, 40, 20]

もし非破壊でシャッフルしたい場合は、random.sample(values, k=len(values))を使うと新しいリストが得られます。

Python
import random

values = [10, 20, 30, 40]
shuffled_new = random.sample(values, k=len(values))  # 新しいリスト
print("元:", values)
print("新しいシャッフル:", shuffled_new)
実行結果
元: [10, 20, 30, 40]
新しいシャッフル: [20, 40, 10, 30]

トランプをシャッフルする例

52枚のトランプデッキを作ってシャッフルし、上から数枚を表示します。

実用的なサンプルとして、デッキ生成→シャッフル→配るの一連の流れを示します。

Python
import random

# スートとランクを定義
suits = ["♠", "♥", "♦", "♣"]
ranks = ["A"] + [str(n) for n in range(2, 10)] + ["10", "J", "Q", "K"]

# 52枚のデッキを生成
deck = [f"{s}{r}" for s in suits for r in ranks]

print("シャッフル前の先頭5枚:", deck[:5])

# 破壊的にシャッフル
random.shuffle(deck)

print("シャッフル後の先頭5枚:", deck[:5])

# 上から5枚配る(取り出し)
hand = deck[:5]
print("配られた手札:", hand)
print("残り枚数:", len(deck) - len(hand))
実行結果
シャッフル前の先頭5枚: ['♠A', '♠2', '♠3', '♠4', '♠5']
シャッフル後の先頭5枚: ['♦Q', '♠8', '♥10', '♣2', '♦6']
配られた手札: ['♦Q', '♠8', '♥10', '♣2', '♦6']
残り枚数: 47

補足として、タプルや文字列はイミュータブルなのでshuffleできません。

その場合はlist()でリスト化してから使います。

まとめ

本記事ではPython標準のrandomモジュールから、randintchoiceshuffleの基本を解説しました。

randintは両端を含む整数、choiceはシーケンスから1件選択、shuffleはリストを破壊的に並び替える点が核となる知識です。

再現性が必要な場面ではrandom.seed()を活用し、セキュリティ用途ではsecretsを選ぶという使い分けも忘れないでください。

これらの基礎が身につけば、ゲームのロジックやデータサンプリングなど、さまざまなプログラムで乱数を安全かつ効果的に扱えるようになります。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

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

URLをコピーしました!