この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: range(連続した整数を生成する)
SEOタイトル: Python range の全パターン(start / stop / step、list 化、enumerate、遅延評価)

この記事の要点
  • range(stop) = 0 〜 stop-1 を生成。stop は含まない
  • range(start, stop) = start 〜 stop-1。range(start, stop, step) で刻み指定
  • range は Lazy(遅延評価)。実体は range オブジェクトでリストではない
  • list(range(...)) で実体化、for i in range(...) でそのままループ可
  • Python 2 の range はリストPython 3 では xrange 統合でメモリ効率良し

range の 3 つの引数パターン

# ① 引数 1 つ: 0 から stop 未満
list(range(5))           # [0, 1, 2, 3, 4]

# ② 引数 2 つ: start から stop 未満
list(range(2, 7))        # [2, 3, 4, 5, 6]

# ③ 引数 3 つ: step 刻み
list(range(0, 10, 2))    # [0, 2, 4, 6, 8]
list(range(10, 0, -1))   # [10, 9, 8, ..., 1]
list(range(0, -10, -2))  # [0, -2, -4, -6, -8]

# step=0 はエラー
range(0, 5, 0)           # ValueError: range() arg 3 must not be zero

典型的な使い方

# ① for ループの回数指定
for i in range(10):
    print(i)             # 0..9

# ② インデックス付きアクセス(enumerate の方が Pythonic)
items = ['a', 'b', 'c']
for i in range(len(items)):
    print(i, items[i])

# ③ より Python らしく
for i, x in enumerate(items):
    print(i, x)

# ④ 範囲指定の逆順
for i in range(len(items) - 1, -1, -1):
    print(items[i])
# あるいは
for x in reversed(items):
    print(x)

# ⑤ ジャンプしながら
for i in range(0, 100, 10):
    print(i)             # 0, 10, 20, ..., 90

range は Lazy(遅延評価オブジェクト)

Python 3 では range はその場でリストを作らず、必要な値を都度計算する遅延オブジェクトです。メモリ効率が良く、range(10**18) でも瞬時に作れます:

r = range(10)
print(type(r))           # 
print(r)                 # range(0, 10)
print(list(r))           # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 巨大 range でも OK(実体化しない)
big = range(10 ** 18)
print(big[500])          # 500 — インデックスアクセス O(1)
print(len(big))          # 1000000000000000000 — O(1)
print(7 in big)          # True — 含有判定も O(1)

# でも list 化すると死ぬ
# list(big)              # MemoryError

range オブジェクトの操作

操作結果計算量
len(r)要素数O(1)
r[i]i 番目の値O(1)
r[i:j]新 rangeO(1)
x in r含有判定O(1)(数値の場合)
list(r)リスト化O(n) ★メモリ注意
reversed(r)逆順 iteratorO(1)

list(range()) でリスト化

nums = list(range(1, 11))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 内包表記と組み合わせて
squares = [i ** 2 for i in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# zip / dict 化
keys = ['a', 'b', 'c']
d = dict(zip(keys, range(len(keys))))
# {'a': 0, 'b': 1, 'c': 2}

enumerate と range の使い分け

items = ['apple', 'banana', 'cherry']

# ❌ C 言語スタイル(非 Pythonic)
for i in range(len(items)):
    print(i, items[i])

# ✅ Pythonic
for i, item in enumerate(items):
    print(i, item)

# 1 始まりにしたい
for i, item in enumerate(items, start=1):
    print(i, item)       # 1 apple, 2 banana, 3 cherry

# 複数リスト同時
names = ['Alice', 'Bob']
ages = [30, 25]
for i, (n, a) in enumerate(zip(names, ages)):
    print(i, n, a)

Python 2 vs Python 3

項目Python 2Python 3
range()list を返すrange オブジェクト(Lazy)
xrange()Lazy(Python 3 の range と同じ)削除
メモリ巨大 range は危険O(1) で安全
含有判定O(n) リスト検索O(1) 算術

浮動小数の range が欲しい場合

range は整数専用です。浮動小数なら NumPy の arange / linspace を使います:

import numpy as np

# 0.0 から 1.0 まで 0.1 刻み
np.arange(0.0, 1.0, 0.1)
# [0.0, 0.1, 0.2, ..., 0.9]

# 0.0 から 1.0 を 11 等分
np.linspace(0.0, 1.0, 11)
# [0.0, 0.1, 0.2, ..., 1.0]

# 自作するなら
def frange(start, stop, step):
    while start < stop:
        yield start
        start += step

list(frange(0, 1, 0.25))
# [0, 0.25, 0.5, 0.75]

FAQ

Q: stop を含めたい(1〜10)
A: range(1, 11) のように stop を +1 する。Python 由来の慣習で stop 非包含です。

Q: range を逆順にしたい
A: range(10, 0, -1) または reversed(range(10))。後者は range オブジェクトを返すので効率的。

Q: list と range のメモリ差は?
A: range(10**6) は数十バイト、list(range(10**6)) は約 8 MB。巨大ループでは range 直接渡しが推奨。