決まった回数だけ処理を繰り返したいとき、Pythonのrange()
を使うと短く、読みやすく書けます。
本記事では0から9まで回す基本から、引数の意味や書き方、オフバイワンの落とし穴、メモリ効率の良さ、そして実用的な例10選までを、Python初心者の方にも分かりやすく丁寧に解説します。
Pythonのrange()基本
0から9まで回す(range(10))
最も基本的な使い方はrange(10)
で0から9まで順に取り出すことです。
for
文と一緒に使うのが一般的です。
# 0から9までを順に表示します
for i in range(10): # 0,1,2,3,4,5,6,7,8,9 を順に生成
print(i)
0
1
2
3
4
5
6
7
8
9
なぜ10で止まるのか
range()
の第1引数は「止める位置」であって「含める最大値」ではないからです。
つまり、range(10)
は0
以上10
未満の整数を生成します。
for文とrange()の使い方(初心者向け)
for
文は「並び」を1つずつ取り出して繰り返す構文です。
range()
はその「並び」を作る道具として最適です。
# メッセージを5回表示します
for i in range(5): # 0から4までの5回
print(f"{i + 1}回目: 処理中...") # 人に見せる番号は1始まりにするのが親切
1回目: 処理中...
2回目: 処理中...
3回目: 処理中...
4回目: 処理中...
5回目: 処理中...
変数名は自由です
取り出した値を受け取る変数名はi
でなくても構いません。
意味が伝わる名前を選ぶと読みやすくなります。
range()の書き方と引数
range()
は3つの形で使えます。
それぞれ生成する数列の範囲や間隔が変わります。
以下に要点を一覧します。
書き方 | 意味 | 例 | 生成される値 |
---|---|---|---|
range(stop) | 0からstop-1まで1刻み | range(5) | 0,1,2,3,4 |
range(start, stop) | startからstop-1まで1刻み | range(3, 7) | 3,4,5,6 |
range(start, stop, step) | startからstep刻み、stopは含まない | range(0, 10, 3) | 0,3,6,9 |
range(stop) 0からstop-1まで
最短の形はrange(stop)
です。
0からstop-1
までの整数を生成します。
# 0から4までのリストを作って表示します
nums = list(range(5)) # [0, 1, 2, 3, 4]
print(nums)
[0, 1, 2, 3, 4]
小数は使えません
range()
の引数は整数のみです。
小数のステップが必要な場合はnumpy.arange
や自作のループで調整します。
range(start, stop) 開始値を指定
開始値を変えたいときはrange(start, stop)
を使います。
# 3,4,5,6 を生成します
print(list(range(3, 7)))
[3, 4, 5, 6]
range(start, stop, step) 間隔や逆順を指定
間引きや逆順にはstep
を指定します。
正の値で前進、負の値で後退します。
# 0から9までを3刻みで
print(list(range(0, 10, 3))) # 0,3,6,9
# 10から1までを2刻みでカウントダウン
print(list(range(10, 0, -2))) # 10,8,6,4,2
[0, 3, 6, 9]
[10, 8, 6, 4, 2]
stepは0にできません
step=0
はエラーです。
前進は正、後退は負にします。
符号が範囲の向きと合わないと空のrange
になります。
range()のコツと注意点
stopは含まない(半開区間)
range()
は常に「start以上、stop未満」の半開区間です。数学の表記では[cst-code>[start, stop)に相当します。
これにより、隣接する範囲を安全に連結できる利点があります。
オフバイワンを防ぐ考え方
「最後に含めたい値の1つ外側をstop
にする」と覚えると、オフバイワンを避けられます。
- 1から10までなら
range(1, 11)
。含めたい上限10の1つ外側は11です。 - 10から1までの逆順なら
range(10, 0, -1)
。含めたい下限1の1つ外側は0です。
print(list(range(1, 11))) # 1..10
print(list(range(10, 0, -1))) # 10..1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
大きい範囲でもメモリ効率が良い
range
は全要素を保持しない「遅延生成するシーケンス」です。
巨大な範囲でも一定のメモリしか使いません。
# 巨大な範囲を作っても一瞬で作れ、少ないメモリしか使いません
r = range(10**12) # 0..999,999,999,999
print(type(r)) # <class 'range'>
print(len(r)) # 要素数の計算は高速
<class 'range'>
1000000000000
何度でも繰り返し使えます
range
は反復可能な「シーケンス」なので、何回ループしても再利用できます。
一度きりの「イテレータ」ではありません。
リスト化はlist(range(…))
必要なときだけlist(range(...))
でリスト化します。
例えば、ソートやインデックスアクセスを頻繁に行う場合です。
ただし巨大範囲のリスト化はメモリを大量消費します。
# 小さな範囲なら手軽にリスト化できます
nums = list(range(5))
print(nums, nums[2]) # リスト化するとインデックス参照がすぐできます
[0, 1, 2, 3, 4] 2
回数指定はrange(n)でn回
単にn回繰り返したいだけならrange(n)
でOKです。
取り出した値を使わないときは変数名に_
を使う慣習があります。
# 3回だけ実行
for _ in range(3):
print("3回繰り返します")
3回繰り返します
3回繰り返します
3回繰り返します
Pythonのrange()実例10選
例1 0から9まで回す(range(10))
range(10)
は「0から始まり、10の手前までの数字」を順番に返します。
つまり「0, 1, 2, …, 9」という10個の数字を取り出す仕組みです。
Pythonのfor文は、このrange
が返す数字を1つずつi
に入れて処理します。
for i in range(10):
print(i, end=" ")
print() # 最後に改行
0 1 2 3 4 5 6 7 8 9
range(10)
の「10」は含まれません。stop
は常に「未満」で終わります。
例2 1から10まで回す(range(1, 11))
上限を含めたいときは1つ外側をstop
にします。
range
はrange(start, stop)
の形で「startからstopの手前まで」を作ります。
10を含めたいなら、stop
を11
にする必要があります。
for i in range(1, 11):
print(i, end=" ")
print()
1 2 3 4 5 6 7 8 9 10
「stopは含まれない」ので、欲しい数字の最大値より1大きい数を指定するのがコツです。
例3 偶数だけ処理する(range(0, 10, 2))
偶数は0から2刻みで取り出せます。
range(start, stop, step)
とすると、step
の分だけ値を飛ばして進みます。
ここでは2
を指定しているので「0から始まり、2ずつ増える」= 偶数だけが出ます。
for i in range(0, 10, 2): # 0,2,4,6,8
print(i, end=" ")
print()
0 2 4 6 8
「1ずつ進む」が基本ですが、step
を変えると簡単に間引きができます。
例4 奇数だけ処理する(range(1, 10, 2))
奇数は1から2刻みです。
偶数のときと同じで、開始値を1
にすれば奇数が取れます。
for i in range(1, 10, 2): # 1,3,5,7,9
print(i, end=" ")
print()
1 3 5 7 9
開始値を変えるだけで「偶数・奇数」を切り替えられます。
例5 カウントダウン(range(10, 0, -1))
逆順は負のstep
で実現します。
step
に負の数を指定すると逆順にカウントできるため、この仕様を利用します。
例えば、range(10, 0, -1)
は「10から1までの数字」を返します。
for i in range(10, 0, -1): # 10,9,...,1
print(i, end=" ")
print()
10 9 8 7 6 5 4 3 2 1
逆順にするときは「start > stop」で「stepを負の値」にする必要があります。
例6 指定回数だけリトライする(range(n))
最大回数を決めてリトライする典型パターンです。
成功したらbreak
で抜けます。
MAX_TRIES = 3
for attempt in range(1, MAX_TRIES + 1):
# ここで実際の処理を行う想定。例として3回目で成功にします
print(f"試行{attempt}回目...", end=" ")
success = (attempt == 3) # 実際は関数の戻り値などで判定
if success:
print("成功")
break
else:
print("失敗")
else:
# breakせずにループが終わったときに実行されます
print("すべて失敗")
試行1回目... 失敗
試行2回目... 失敗
試行3回目... 成功
for-else
は「途中でbreakしなかった場合」に実行される構文です。
例7 二重ループで行×列を回す(range(rows), range(cols))
二重ループでグリッド状の座標を総当たりします。
「外側のループ = 行」「内側のループ = 列」と覚えると理解しやすいです。
rows, cols = 2, 3
for r in range(rows): # 行: 0,1
for c in range(cols): # 列: 0,1,2
print(f"({r}, {c})", end=" ")
print() # 行の終わりで改行
(0, 0) (0, 1) (0, 2)
(1, 0) (1, 1) (1, 2)
プログラミングでよく出る「行と列」を扱う基礎パターンです。
例8 N件ごとに処理する(stepで間引き)
一定間隔で要素を間引いて処理します。
インデックスをrange(0, len(data), N)
で走らせるのが簡単です。
data = list(range(1, 21)) # 1..20
N = 5
for i in range(0, len(data), N): # 0,5,10,15
print(f"index={i}, value={data[i]}")
index=0, value=1
index=5, value=6
index=10, value=11
index=15, value=16
データを「間引きながら」処理したいときに便利です。
例9 チャンク処理(range(0, n, chunk_size))
大きな配列を固定サイズの塊に分けて処理します。
今回紹介するサンプルの中で一番複雑ですが、start:start+chunk_size
でスライスすれば部分配列が取れます。
data = list(range(1, 13)) # 1..12
chunk_size = 4
for start in range(0, len(data), chunk_size):
chunk = data[start:start + chunk_size] # 部分配列をスライス
print(f"chunk@{start}-{start+len(chunk)-1}: {chunk}")
chunk@0-3: [1, 2, 3, 4]
chunk@4-7: [5, 6, 7, 8]
chunk@8-11: [9, 10, 11, 12]
データを一定サイズに区切って処理する「バッチ処理」の基礎です。
例10 rangeの長さを確認する(len(range(…)))
len()
で要素数を即座に取得できます。
実際に数字を作らず(カウント用の変数不要)に数えるので、メモリを消費せずに数えられます。
print(len(range(10))) # 0..9 の10個
print(len(range(1, 11))) # 1..10 の10個
print(len(range(10, 0, -1))) # 10..1 の10個
10
10
10
大量のデータでもメモリを使わずに「要素数だけ」確認できます。
まとめ
Pythonのrange()
は「決まった回数だけ繰り返す」を最短で書ける基本ツールです。
半開区間のルールを押さえ、range(stop)
やrange(start, stop, step)
の3形態を使い分ければ、オフバイワンを避けつつ、前進・後退・間引き・チャンク処理まで幅広く対応できます。
加えてrange
はメモリ効率が良く、len(range(...))
で素早く要素数も把握できます。
本記事の10例を手元で動かしながら慣れていけば、for文とrange()
だけで多くの処理をシンプルに書けるはずです。