Pythonのrandom入門!choice・sample・shuffleの違いを席替えとくじ引きで理解する
「Pythonでランダムに選ぶって、どの関数を使えばいいの?」「choiceとsampleとshuffle、違いがよくわからない…」
ランダムな処理は、くじ引きやクイズの出題順、席替えなど、身近なプログラムでよく使いますよね。でも関数が似ているので、最初は迷いやすいところです。
この記事では、標準ライブラリの random モジュール を使って、席替えプログラム と 確率つきのくじ引き を作ります。インストールは不要で、Python が入っていればすぐ試せます😊
- 難易度:★☆☆(for文とリストがわかればOK)
- 対象:Python入門〜初級の方
- 動作確認:Python 3.13
まずは基本の5つを動かしてみよう

random モジュールでよく使う関数は、この5つです。イメージとしては「何を・何個・重複ありかなしか」で使い分けます。
| 関数 | やること | 戻り値 |
|---|---|---|
randint(a, b) |
a以上b以下の整数を1つ | 整数 |
random() |
0.0以上1.0未満の小数を1つ | 小数 |
choice(リスト) |
リストから1つ選ぶ | 要素1つ |
sample(リスト, k) |
重複なしでk個選ぶ | 新しいリスト |
shuffle(リスト) |
リストそのものを並べ替える | None |
実際に動かしてみましょう👇
import random
random.seed(42) # 毎回同じ結果にしたいときだけ指定
print("サイコロ:", random.randint(1, 6)) # 1〜6(6も含む)
print("0〜1の小数:", round(random.random(), 3)) # 0.0以上1.0未満
menu = ["カレー", "ラーメン", "寿司", "パスタ"]
print("今日のランチ:", random.choice(menu)) # 1つ選ぶ
print("2人の当番:", random.sample(menu, 2)) # 重複なしで2つ
cards = [1, 2, 3, 4, 5]
random.shuffle(cards) # 元のリストを並べ替える
print("シャッフル後:", cards)

ポイントをまとめるとこんな感じです。
randint(1, 6)は 6も含みます。range(1, 6)とは違うので注意ですrandom.seed(42)を書くと、何回実行しても同じ結果になります。実際に2回実行して、まったく同じ出力になることを確認しました- テストや記事の説明のように「結果をそろえたい」とき以外は、seed は書かなくてOKです
⚠️ shuffle の戻り値は None
ここでクイズです。cards = random.shuffle(cards) と書くと、cards の中身はどうなるでしょう? 実行せずに答えられますか?
答えは None です。shuffle は元のリストを直接並べ替えて、何も返さない関数だからです。初心者がとてもつまずきやすいところなので、shuffle は代入せずに単独で書くと覚えておきましょう。
席替えプログラムを作ろう
次は、9人を3列に並べる席替えです。ここが重要です👇
names[:]で コピーしてから shuffle する(元の名簿を壊さない)random.Random(seed)で 席替え専用の乱数を作る(ほかの処理の乱数に影響しない)- スライスで3人ずつ区切って「列」にする
import random
members = ["佐藤", "鈴木", "高橋", "田中", "伊藤", "渡辺", "山本", "中村", "小林"]
COLS = 3 # 1列に3席
def make_seats(names, seed=None):
rng = random.Random(seed) # 席替え専用の乱数(seedで再現できる)
shuffled = names[:] # コピーしてから混ぜる(元の名簿は変えない)
rng.shuffle(shuffled)
# 3人ずつ区切って「行」にする
return [shuffled[i:i + COLS] for i in range(0, len(shuffled), COLS)]
seats = make_seats(members, seed=2026)
print("【教卓】")
for row_no, row in enumerate(seats, start=1):
print(f"{row_no}列目: " + " | ".join(f"{name: <3}" for name in row))
print("名簿はそのまま:", members[:3], "...")
print("同じseedなら同じ結果:", make_seats(members, seed=2026) == seats)
実行結果です。
【教卓】
1列目: 中村 | 田中 | 高橋
2列目: 小林 | 佐藤 | 山本
3列目: 伊藤 | 渡辺 | 鈴木
名簿はそのまま: ['佐藤', '鈴木', '高橋'] ...
同じseedなら同じ結果: True
名簿の順番は変わっておらず、同じ seed を渡すと同じ席順が再現できました。つまり「先生がやり直しを求められても、同じ番号で同じ結果を見せられる」ということです。
ちなみに sample(members, len(members)) でも、元のリストを変えずに並べ替えた新しいリストが作れます。元を残したいなら sample、その場で混ぜたいなら shuffle と使い分けるとスッキリしますよ。
確率つきのくじ引きを作ろう
「1等は2%、はずれは70%」のように、当たりやすさに差をつけたいときは random.choices() を使います。weights に重み、k に引く回数を渡します。choices は 重複ありで選ぶ ので、何回でも同じ賞が出ます。
import random
from collections import Counter
prizes = ["はずれ", "3等", "2等", "1等"]
weights = [70, 20, 8, 2] # 合計100 → そのまま「%」として読める
random.seed(1)
print("10回引く:", random.choices(prizes, weights=weights, k=10))
# 1万回引いて、本当に設定どおりの割合になるか確かめる
results = Counter(random.choices(prizes, weights=weights, k=10000))
for prize, w in zip(prizes, weights):
rate = results[prize] / 10000 * 100
print(f"{prize: <3}: {results[prize]:>5}回 ({rate:4.1f}%) 設定 {w}%")

1万回引いた結果は 70.2% / 19.5% / 8.3% / 2.1% で、設定した 70 / 20 / 8 / 2% にかなり近くなりました。少しズレるのは、ランダムなので当然です。回数を増やすほど、設定値に近づいていきます。
このように 「たくさん試して割合を数える」 と、確率の設定ミスを自分で確かめられます。Counter の使い方も一緒に覚えておくと便利ですね。
⚠️ パスワードには random ではなく secrets
random モジュールは、ゲームやシミュレーション用です。公式ドキュメントにも、セキュリティ目的には使わないようにと書かれています。
パスワードやログイン用のトークンを作るときは、同じく標準ライブラリの secrets モジュールを使いましょう。secrets.choice(文字の一覧) を12回くり返して12文字のパスワードを作ったところ、p5fllXMmAI2g のような文字列ができました(実行するたびに変わります)。
まとめ
- 1つ選ぶなら
choice、重複なしで複数ならsample、重みつきで複数ならchoices shuffleは元のリストを並べ替えてNoneを返す。代入しないrandint(a, b)は b も含むseedやrandom.Random(seed)で結果を再現できる- パスワードなどセキュリティ用途は
secrets
関数の違いがわかると、ランダムな処理は「むずかしそう」から「できそう」に変わるはずです。クイズの出題順を混ぜたり、今日の献立を決めたり、ぜひ身近なネタで試してみてください🚀
\ 読んだら、次は自分で作ってみよう /
筆者が運営する無料の入門コース「作って学ぶPythonプログラミング入門」では、こうした基本文法を、割り勘計算機・おみくじ・数当てゲームなどを作りながら身につけます。各章末の定着ドリル(全42問)で、自分の手で書く練習まで。最初の4レッスンは登録なしで読めます。
こちらも読まれています
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。




