【2026年9月最新】Pythonのrandomモジュールの使い方を完全解説|choice・sample・seedからセキュリティ注意点まで
Pythonで乱数(ランダムな値)を使いたいとき、多くの人が最初に手を伸ばすのが標準ライブラリのrandomモジュールです。random.randint()やrandom.choice()は初心者向けの教材でもよく登場しますが、実は「どの関数を使うべきか」を正しく理解していないと、意図しないバグやセキュリティ上のリスクにつながることがあります。
この記事では、randomモジュールの基本関数を整理したうえで、初心者向け教材では見落とされがちなrandom.choices()とrandom.sample()の違い、seed()による再現性の確保、そして最も重要な「パスワードやトークンの生成にrandomモジュールを使ってはいけない理由」まで、実務目線で踏み込んで解説します。最後には、Claude Codeを使ったテストデータ生成の効率化についても紹介します。
01 OVERVIEW randomモジュールとは何か 疑似乱数を生成する標準ライブラリ
randomモジュールは、Pythonの標準ライブラリに含まれる、疑似乱数(コンピュータが計算によって作り出す、一見ランダムに見える数値)を生成するためのモジュールです。追加のインストールは不要で、import randomと書くだけですぐに使えます。
📚 用語解説
疑似乱数(ぎじらんすう):コンピュータが数式(アルゴリズム)によって計算的に生成する、統計的にはランダムに見える数値のこと。真の意味でランダム(物理現象などに基づく真性乱数)ではなく、同じ初期値(シード値)から計算を始めれば、毎回まったく同じ数列を再現できるという特徴を持つ。Pythonのrandomモジュールは「メルセンヌ・ツイスタ」というアルゴリズムを採用している。
ゲームのサイコロ処理、抽選、テストデータの生成、シミュレーションなど、randomモジュールの用途は多岐にわたります。まずは基本となる3つの関数から見ていきましょう。
02 BASIC FUNCTIONS 基本の乱数取得:random・uniform・randint 3つの関数の違いを正確に理解する
2-1. random.random():0以上1未満の小数
import random
print(random.random())
# 0.7364258172645... (0.0以上1.0未満の浮動小数点数)
random.random()は引数を取らず、0.0以上1.0未満の浮動小数点数を返します。ここで得られる値を元に、他の多くの乱数関数が内部的に計算されています。
2-2. random.uniform(a, b):指定範囲の小数
import random
print(random.uniform(1.0, 10.0))
# 4.281839...(1.0以上10.0以下のいずれかの浮動小数点数)
random.uniform(a, b)は「aからbの範囲」の値を返しますが、公式ドキュメントでも「浮動小数点の丸め誤差により、終端値bちょうどが返る場合と返らない場合がある」と説明されています。「bは絶対に含まれない」と断定せず、範囲の目安として捉えるのが正確な理解です。
2-3. random.randint(a, b):指定範囲の整数
import random
print(random.randint(1, 6))
# 1〜6のいずれかの整数(サイコロを想定した例)
random.randint(a, b)はaとbの両方を含む範囲から整数を返します。似た関数のrandom.randrange(a, b)は逆にbを含まない(range()と同じ仕様)ため、「1〜10」を意図してrandrange(1, 10)と書くと9までしか出ない、という初心者が混同しやすい違いがあります。
| 関数 | 戻り値の型 | 範囲の指定方法 | 端点の扱い |
|---|---|---|---|
| random.random() | 浮動小数点数 | 固定(0.0〜1.0) | 0.0以上1.0未満 |
| random.uniform(a, b) | 浮動小数点数 | a〜bを指定 | ほぼa以上b以下(丸め誤差の影響あり) |
| random.randint(a, b) | 整数 | a〜bを指定 | a以上b以下(両端含む) |
| random.randrange(a, b) | 整数 | a〜bを指定 | a以上b未満(range()と同じ) |
03 LIST OPERATIONS リストからのランダム抽出:choice・choices・sample 重複あり・なしの違いを正しく使い分ける
3-1. random.choice():1つだけ選ぶ
import random
fruits = ['apple', 'banana', 'orange']
print(random.choice(fruits))
# 'banana' (3つの中からランダムに1つ)
3-2. random.choices():重複ありで複数選ぶ
import random
fruits = ['apple', 'banana', 'orange']
print(random.choices(fruits, k=5))
# ['banana', 'banana', 'apple', 'orange', 'banana']
# ※ 同じ要素が複数回選ばれることがある(重複あり)
# weightsで重み付けもできる
print(random.choices(fruits, weights=[10, 1, 1], k=5))
# appleが選ばれやすくなる(重みが大きいほど当選確率が上がる)
3-3. random.sample():重複なしで複数選ぶ
import random
fruits = ['apple', 'banana', 'orange', 'grape', 'melon']
print(random.sample(fruits, k=3))
# ['grape', 'apple', 'orange']
# ※ 同じ要素は二度選ばれない(重複なし)
📚 用語解説
復元抽出 / 非復元抽出:統計学の用語で、一度選んだ要素を「元に戻してから」次を選ぶ方式を復元抽出(重複あり)、「元に戻さず」次を選ぶ方式を非復元抽出(重複なし)と呼ぶ。random.choices()は復元抽出、random.sample()は非復元抽出にあたる。くじ引きで「引いたくじを戻すか戻さないか」の違いをイメージすると分かりやすい。
抽選会で「当選者を3人選ぶ」処理にrandom.choices()を使ってしまうと、同じ人が複数回当選する可能性があります。重複を許したくない用途では必ずrandom.sample()を使ってください。逆に、サイコロを5回振るシミュレーションのように「同じ目が複数回出てよい」場面ではchoices()が適切です。
| 関数 | 重複 | 主な用途 |
|---|---|---|
| random.choice() | (1件のみ取得) | 1つだけランダムに選びたいとき |
| random.choices(seq, k=n) | あり(復元抽出) | サイコロのシミュレーション、重み付き抽選 |
| random.sample(seq, k=n) | なし(非復元抽出) | 重複のない当選者選出、抜き取り検査のサンプリング |
3-4. random.shuffle():リストの中身を入れ替える
import random
cards = ['A', 'B', 'C', 'D', 'E']
random.shuffle(cards)
print(cards)
# ['C', 'A', 'E', 'B', 'D'] (元のリストが直接並び替えられる)
random.shuffle()はリストを直接その場で並び替える(破壊的処理)関数で、戻り値は常にNoneです。cards = random.shuffle(cards)のように代入してしまうと、cardsの中身がNoneになって消えてしまいます。「シャッフルした新しいリストが欲しい」場合は、shuffle()ではなく後述のsample()で全件数を指定する方法を使います。
import random
cards = ['A', 'B', 'C', 'D', 'E']
# 元のリストを変えずに、シャッフル済みの新しいリストを得る方法
shuffled = random.sample(cards, k=len(cards))
print(cards) # ['A', 'B', 'C', 'D', 'E'] (元のリストは変わらない)
print(shuffled) # ['D', 'A', 'C', 'E', 'B'] (新しいシャッフル済みリスト)
04 REPRODUCIBILITY seed()で乱数を固定・再現する テストやデバッグで「同じ乱数」を再現する方法
randomモジュールが生成する値は「疑似」乱数であるため、開始点(シード値)を固定すれば、何度実行してもまったく同じ結果を再現できます。この性質は、テストやデバッグの場面で非常に役立ちます。
import random
random.seed(42)
print(random.randint(1, 100)) # 82
print(random.randint(1, 100)) # 15
# 同じseed(42)からやり直すと、まったく同じ順番で同じ値が出る
random.seed(42)
print(random.randint(1, 100)) # 82 (1回目と同じ)
print(random.randint(1, 100)) # 15 (2回目と同じ)
📚 用語解説
シード値(seed):疑似乱数の計算を開始する際の「初期値」のこと。同じシード値を指定すれば、生成される乱数の順番は毎回まったく同じになる。テストコードで「ランダムな入力を使うが、実行するたびに結果が変わると再現性がなく困る」という場面で、seed()を使って乱数を固定するのが定石。
「ランダムな要素を含む処理」をテストする場合、実行のたびに結果が変わってしまうと、バグの再現や修正確認が難しくなります。テストの冒頭でrandom.seed(固定値)を呼んでおくことで、乱数が絡む処理でも決まった結果を期待するテストコードが書けます。
デバッグ用にseed()を設定したまま本番コードに残してしまうと、常に同じ「ランダムな」結果しか出なくなるという不具合になります。抽選やゲームなど、本来毎回変わってほしい処理では、デバッグ後に必ずseed()の呼び出しを削除してください。
4-1. モンテカルロシミュレーションでの活用例
seed()による再現性は、モンテカルロシミュレーション(乱数を使って試行を大量に繰り返し、統計的な傾向を推定する手法)でも重要な役割を果たします。例えば、あるキャンペーンの当選確率を試算する場合を考えてみます。
import random
random.seed(1)
trials = 10000
win_count = 0
for _ in range(trials):
if random.random() < 0.05: # 当選確率5%と仮定
win_count += 1
print(f'{trials}回試行して{win_count}回当選(実測確率: {win_count / trials:.2%})')
# 10000回試行して537回当選(実測確率: 5.37%)
📚 用語解説
モンテカルロシミュレーション:乱数を使って大量の試行を繰り返し、その結果の統計的な傾向から、理論的に解くのが難しい問題の近似解を求める手法。金融のリスク計算、在庫戦略の検証、ゲームバランスの調整など幅広い分野で使われる。random.seed()で試行の再現性を確保しておくと、パラメータを変えたときの効果の比較がしやすくなる。
このように、「同じ条件で何度も試行した場合の傾向」を調べたい業務シーンでは、seed()で再現性を確保しつつ、randomモジュールの各関数を組み合わせて試算するアプローチが実務でも活用されています。
05 SECURITY WARNING 【重要】パスワード生成にrandomを使ってはいけない理由 セキュリティ用途にはsecretsモジュールを使う
プログラミング入門記事では、random.choice()と文字列を組み合わせて「ランダムなパスワードを生成する」サンプルコードがよく紹介されます。しかし、この方法を実際のサービスのパスワードやAPIトークン、パスワードリセット用のURLなどに使うのは危険です。
5-1. randomモジュールが「予測可能」である理由
Pythonのrandomモジュールは、メルセンヌ・ツイスタという高速なアルゴリズムで疑似乱数を生成しています。統計的な均一性には優れていますが、暗号学的には安全ではありません。十分な数の出力を観測されると、内部状態を推測され、以降に生成される値を予測されてしまう可能性があることが知られています。
📚 用語解説
メルセンヌ・ツイスタ(Mersenne Twister):Pythonのrandomモジュールが採用している疑似乱数生成アルゴリズム。周期が非常に長く、統計的な品質にも優れているためシミュレーションやゲームの用途では広く使われている。ただし、生成される数列にはアルゴリズム由来の規則性があり、十分な数の出力から内部状態を復元できてしまうため、暗号やセキュリティ用途には適さないとされている。
5-2. セキュリティ用途にはsecretsモジュールを使う
パスワード、トークン、セッションID、パスワードリセット用のURLなど、「他人に予測されては困る」値を生成する場合は、Python標準ライブラリのsecretsモジュールを使います。secretsモジュールはOSが提供する暗号学的に安全な乱数源を利用しており、この目的のために標準ライブラリ側でも明確に推奨されています。
import secrets
import string
# 安全なランダムパスワードを生成する例
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for _ in range(12))
print(password)
# 例: 'aB3xQ9mK7pLz'
# 安全なトークンを生成する(URLセーフな文字列)
token = secrets.token_urlsafe(32)
print(token)
| 用途 | 使うべきモジュール | 理由 |
|---|---|---|
| ゲームのサイコロ・くじ引き | random | 予測されても実害がない、速度と手軽さを優先してよい |
| シミュレーション・統計処理 | random | 再現性(seed固定)が必要なことも多く、randomが適している |
| テストデータの生成 | random | ダミーデータなので、予測可能性は問題にならない |
| パスワード・トークンの生成 | secrets | 予測されると不正アクセスなど実害につながるため |
| パスワードリセット用URL | secrets | 第三者に推測されると本人以外がリセットできてしまうため |
random.choice()で生成したパスワードも、見た目上はランダムに見え、機能としては正常に動作します。しかし「予測可能かどうか」という安全性の観点は、動作確認だけでは検出できません。パスワード・トークン生成のコードを見かけたら、使われているのがrandomかsecretsかを必ず確認する習慣をつけてください。
06 PRACTICAL EXAMPLE ランダム文字列生成の実践例 stringモジュールとの組み合わせ
セキュリティ要件が絡まない用途(テストデータのダミーIDなど)であれば、randomモジュールとstringモジュールを組み合わせたランダム文字列生成は今でも実務でよく使われます。
import random
import string
def generate_dummy_id(length=8):
chars = string.ascii_uppercase + string.digits
return ''.join(random.choices(chars, k=length))
for _ in range(3):
print(generate_dummy_id())
# 例:
# 'K3F9XQ2P'
# 'A7B2ZZ81'
# 'M0QW5T4C'
📚 用語解説
string.ascii_uppercase / string.digits:Python標準ライブラリのstringモジュールが提供する定数。ascii_uppercaseは大文字アルファベット26文字('ABCDEFGHIJKLMNOPQRSTUVWXYZ')、digitsは数字10文字('0123456789')を表す文字列。ランダムな識別子を組み立てる際の元となる文字集合として頻繁に利用される。
この例のように「重複しても実害がない、セキュリティに関わらないダミーデータ」を作る場合は、random.choices()で十分です。逆に「他人に推測されると困る」文脈が少しでもあれば、前章のsecretsモジュールに切り替えるという判断を徹底してください。
07 COMMON MISTAKES よくある間違い・チェックリスト 実装前に確認しておきたいポイント
特に最後の項目は、コードが正常に動作するため見過ごされがちです。「機能テストは通っているのに、セキュリティレビューで指摘される」典型的なパターンなので、パスワード・トークン生成のコードを書く・レビューする際は必ず確認してください。
問題ないか?
ゲーム・統計・
テストデータ
choice/choices/
sample/shuffle
パスワード・
トークン生成
08 AI-ASSISTED DATA GENERATION 【独自】Claude Codeを使ったテストデータ生成・シミュレーション効率化 AIコーディングアシスタントに任せられる範囲を見極める
randomモジュールの代表的な用途の1つがテストデータの生成です。しかし、「氏名・住所・注文金額・在庫数がそれぞれ現実的な分布になっているダミーデータを100件作る」といった要件になると、手作業でコードを組むのは意外と手間がかかります。
ここで役立つのが、Claude CodeのようなAIコーディングアシスタントです。「こういう構造・分布のテストデータを、randomモジュールを使って生成するスクリプトを書いて」と依頼すると、要件に合わせたコードをその場で組み立ててくれます。
| 依頼内容 | AIへの指示例 |
|---|---|
| 基本的なダミーデータ生成 | 「氏名・年齢・購入金額を持つダミー顧客データを100件、randomで生成するスクリプトを書いて」 |
| 重み付きのシミュレーション | 「発生確率が異なる3種類のイベントを1000回試行するシミュレーションを、random.choices()の重み付けで実装して」 |
| 再現性のあるテストケース | 「このテストコードに、乱数の結果を固定するseed()を追加して」 |
| セキュリティ観点のチェック | 「このコードでパスワード生成にrandomモジュールが使われていないか確認して」 |
欲しいテストデータの
条件をAIに伝える
生成スクリプトの
たたき台を受け取る
分布・件数を
調整して実行
セキュリティ用途は
secretsに置換
AIが提示するコードも、テストデータ生成の文脈で書かれていれば当然randomモジュールを使います。そのコードをうっかりパスワード生成など別の用途に転用しないよう、最終的なチェックは人間が行うようにしましょう。
09 GENAI CASE STUDY 【独自データ】GENAI社内でのPython活用実例 Claude Max 20xプランでの活用実態
弊社(株式会社GENAI)では、Claude Max 20xプラン(月額$200・約30,000円)を契約し、営業・広告運用・記事制作・経理・秘書業務まで、社内のあらゆる業務でPythonスクリプトを活用しています。
| 業務領域 | 主な用途 | randomモジュールの使いどころ |
|---|---|---|
| 広告運用 | A/Bテスト設計のシミュレーション | random.choices()で配信パターンの重み付けをシミュレーション |
| ブログ記事 | サムネイル画像の重複回避ロジック | random.sample()で未使用の候補から選択 |
| 開発・テスト | デモ環境用のダミーデータ生成 | random + stringでテスト用の識別子を大量生成 |
一方で、顧客向けサービスの認証まわり(パスワード再設定用のトークンなど)は、この記事で説明した理由からsecretsモジュールに統一するようルール化しています。「どちらのモジュールを使うか」を毎回個別に判断するのではなく、用途ごとにあらかじめ方針を決めておくことで、レビューの手間を減らしています。
上記は弊社での活用例であり、業種・業態によって最適な使い分けは異なります。あくまで参考情報としてご覧ください。
10 CONCLUSION まとめ randomモジュールを正しく使い分ける
randomモジュールは手軽に使える便利なツールですが、「重複の有無」「戻り値の型」「再現性」「セキュリティ上の安全性」といった性質を正しく理解しているかどうかで、コードの品質に大きな差が出ます。特にセキュリティに関わる用途でsecretsモジュールへの切り替えを意識できているかは、実務のコードレビューでも重要なチェックポイントです。
弊社では、こうした基礎的な技術判断を含めて、Claude Codeを活用した業務自動化・システム開発の設計から伴走支援まで行っています。「社内のコード品質を底上げしたい」という方は、ぜひ一度ご相談ください。
コード品質の底上げ・Claude Code導入も、AI鬼管理が伴走します
randomとsecretsの使い分けのような基礎判断の積み重ねが、システム全体の信頼性を左右します。
AI鬼管理では、Claude Codeを活用した業務自動化の設計から、社内エンジニア以外のメンバーへの定着支援まで対応しています。
ここから先の進め方は、大きく2つあります。
自社で回せるようになりたい方は、AI鬼管理でClaude Code/Codexの使い方から業務設計・社内定着まで伴走を受けながら、社内に仕組みを作る道があります。
覚えるより任せたい方は、AI社員AIKATAでこの記事のような定型業務を丸ごと預ける道があります。料金は月30万円の月額定額、追加費用は0円です。
どちらが合うかは、業務量と社内体制次第です。無料相談・無料適合診断で、貴社の場合はどちらが向くかからご相談いただけます。
NEXT STEP
この記事の内容を、あなたのビジネスで
実践してみませんか?
よくある質問
Q. random.randint()とrandom.randrange()の違いは何ですか?
A. random.randint(a, b)はaとbの両方を含む範囲から整数を返します。一方random.randrange(a, b)はrange()と同じ仕様で、bを含まない範囲から整数を返します。「1〜10」を意図してrandrange(1, 10)と書くと9までしか出ない点に注意が必要です。
Q. random.choices()とrandom.sample()はどう使い分けますか?
A. random.choices()は重複ありで複数要素を選ぶ関数で、同じ要素が複数回選ばれることがあります。random.sample()は重複なしで選ぶ関数です。抽選会の当選者選びのように重複を避けたい場合はsample()、サイコロを複数回振るシミュレーションのように重複してよい場合はchoices()を使います。
Q. random.shuffle()の戻り値をprintしても何も表示されないのはなぜですか?
A. random.shuffle()はリストを直接その場で並び替える関数で、戻り値は常にNoneだからです。シャッフルした結果を確認したい場合は、shuffle()を実行した後のリストそのものをprintしてください。変数に代入すると中身がNoneになって消えてしまうので注意が必要です。
Q. なぜパスワード生成にrandomモジュールを使ってはいけないのですか?
A. Pythonのrandomモジュールはメルセンヌ・ツイスタというアルゴリズムを使っており、統計的な品質は高いものの暗号学的には安全ではありません。十分な数の出力を観測されると内部状態を推測され、生成される値を予測される可能性があります。パスワードやトークンなど予測されると困る用途には、暗号学的に安全なsecretsモジュールを使ってください。
Q. seed()を使うとどんなメリットがありますか?
A. 同じシード値を指定すれば、生成される乱数の順番を毎回同じにできるため、テストやデバッグで結果を再現しやすくなります。ランダムな要素を含む処理のテストコードを書く際、seed()で乱数を固定しておくことで、実行結果が安定した検証が可能になります。
Q. テストデータの生成にrandomモジュールを使うのは問題ありませんか?
A. 問題ありません。テストデータやダミーデータのように「予測されても実害がない」用途であれば、randomモジュールで十分です。セキュリティ上の注意が必要になるのは、パスワードやトークンなど、他人に予測されると実際の被害につながる値を生成する場合に限られます。
Claude Codeで業務自動化を90日で叩き込む
経営者向けの伴走型パーソナルトレーニング
AI鬼管理/AI社員AIKATAへのお問い合わせ
この記事を読んで気になった方へ。
専門スタッフが、御社に最適な
業務自動化・業務代行プランを無料でご提案します。




