ループで素数を列挙する

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

ループで素数を列挙する とは

for と while を組み合わせて、n 以下の素数を昇順に並べたリストを返すアルゴリズムを実装する。

ループで素数を列挙する

ループの応用編として、素数 (prime number) の列挙にチャレンジします。素数とは「1 と自分自身以外で割り切れない、2 以上の整数」のことです。2, 3, 5, 7, 11, 13, ... と続きます。本レッスンでは、整数 n を受け取り、n 以下の素数を昇順に並べたリストを返す関数を、入れ子ループで実装します。

素数判定は古典的なアルゴリズム題材で、ループの理解度を試す良いトレーニングです。

素数判定の方針

判定の最も基本的な形は、「2 から 候補値 - 1 まで全部試して、どれでも割り切れなければ素数」というものです。さらに賢くする方法もありますが、まずはシンプルに書きましょう。

  • n < 2 のとき、その数は素数ではない
  • n == 2 のとき、最小の素数として認める
  • それ以外は i = 2, 3, ..., n - 1 を試し、1 つでも割り切れたら素数ではない

Python

def is_prime(n): if n < 2: return False for i in range(2, n): if n % i == 0: return False return True

n % i == 0 は「ni で割り切れる」という意味です。割り切れる i が見つかった瞬間に return False で関数を抜け、見つからずループを抜けたら return True で素数だと判定します。

for ループの外で True を返す形は、線形探索 + 否定 のお決まりパターンです。

列挙する関数の組み立て

素数判定ができれば、2..n を回しながら判定を呼ぶだけで、素数のリストが手に入ります。

Python

def list_primes(n): result = [] for candidate in range(2, n + 1): is_prime = True for i in range(2, candidate): if candidate % i == 0: is_prime = False break if is_prime: result.append(candidate) return result

外側のループで判定したい candidate を 1 つずつ取り出し、内側のループで 2..candidate - 1 を試します。割り切れる数があれば break で早期離脱し、is_prime フラグを False にします。最後にフラグが True のままなら、result に追加します。

break は内側のループだけ抜けます。外側はそのまま動き続けます。

動きを追ってみる

n = 10 のときの流れを簡略化したフローで示します。

diagram (will load when visible)

n = 10 のとき、判定対象は 2, 3, 4, ..., 10。素数と判定されるのは 2, 3, 5, 7 で、結果は [2, 3, 5, 7] です。

よくある間違い

素数の列挙でつまずきやすいポイントは次の通りです。

  • n 以下なのに range(2, n) と書いて n 自身を判定し忘れる
  • is_prime = True の初期化を内側ループ前ではなく に置く
  • 内側ループで break し忘れて、最後まで全部試して遅くなる
  • n % i == 0n / i == 0 と書き間違える
  • n < 2 のチェックを忘れて、01 を素数として返す

Python

# NG: フラグの初期化を外側ループの外に置いてしまった is_prime = True for candidate in range(2, n + 1): for i in range(2, candidate): if candidate % i == 0: is_prime = False break if is_prime: result.append(candidate)

このコードでは、is_prime が一度 False になると 二度と True に戻らない ので、2 以外の全部の数が「合成数」と判定されてしまいます。フラグは判定する数ごとに初期化するのが鉄則です。is_prime = True の位置を必ず内側ループの に置きましょう。

入れ子ループでフラグを使うときは、「どの繰り返しごとに初期化するか」を強く意識します。

やってみよう

このレッスンでは、整数 n を受け取り、n 以下の素数を昇順に並べたリストを返す関数 list_primes(n) を実装します。n1 以下のときは空リストを返してください。n = 10 のときの結果は [2, 3, 5, 7]n = 20 のときは [2, 3, 5, 7, 11, 13, 17, 19] です。外側のループで候補を回し、内側のループで割り切れる数を探す、という典型的な入れ子の使い方を体に染み込ませましょう。

余裕があれば、内側ループの上限を int(candidate ** 0.5) + 1 にすると高速化できることも確認してみましょう。

よくある質問

Q. このトピックは Python 以外の言語でも同じ書き方ですか?

A. 考え方は他言語と共通ですが、構文や標準ライブラリは異なります。Python はインデントでブロックを表し、コロン + 改行で構造を作るのが特徴です。他言語に移行する際は基本概念を維持しつつ、構文の差分を意識して書き換えると混乱が少ないです。

Q. 実行してエラーが出た場合の対処は?

A. エラーメッセージの最後の行(TypeError や NameError などの型)から原因と該当行を確認します。Python はトレースバックが下から上に読むと「呼び出し元 → 内部」の順で辿れます。print や IDE のデバッガで途中の変数を確認すると原因が見えてきます。

Q. 次のステップで何を学ぶべきですか?

A. 本レッスンの内容を理解できたら、本文の「やってみよう」を実装し、章末クイズに進むのがおすすめです。さらに自分のミニアプリ(電卓・todo・スコア集計など)に応用するとスキルが定着します。詰まったら本文の H2 セクションに戻って読み返してください。

次のレッスン

次は 第 5 章クイズ ループ で、for と while を組み合わせて、n 以下の素数を昇順に並べたリストを返すアルゴリズムを実装する を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. 素数判定 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 素数判定 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 外側の for で 2..n を回すこと
  2. 内側の for で割り切れる数を探すこと
  3. 戻り値は素数を昇順に並べたリストにすること

入出力例

test-cases.txt

list_primes(10)[2,3,5,7] list_primes(1)[] list_primes(2)[2] list_primes(20)[2,3,5,7,11,13,17,19] list_primes(0)[]

ヒント

main.py
main.py
学習モード

メモ

ループで素数を列挙する

⌘S で保存