【Python】range関数完全ガイド2025年版 – 基礎から難関テクニックまで
Pythonのrange関数とは?基本概念の理解
range関数は、Pythonにおいて連続する整数のシーケンスを生成する組み込み関数です。forループでの反復処理において最も頻繁に使用され、メモリ効率の良いイテレータオブジェクトを返します。range関数を深く理解することで、より効率的で読みやすいPythonコードを書くことができます。
基礎編:range関数の基本的な使い方
基本構文とシンプルな使用例
# 基本的な使い方:0から4まで
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# 開始値と終了値を指定
for i in range(2, 8):
print(i) # 2, 3, 4, 5, 6, 7
# ステップ値を指定
for i in range(0, 10, 2):
print(i) # 0, 2, 4, 6, 8
range関数の3つの引数パターン
# パターン1: range(stop)
numbers1 = list(range(5))
print(numbers1) # [0, 1, 2, 3, 4]
# パターン2: range(start, stop)
numbers2 = list(range(3, 8))
print(numbers2) # [3, 4, 5, 6, 7]
# パターン3: range(start, stop, step)
numbers3 = list(range(1, 11, 2))
print(numbers3) # [1, 3, 5, 7, 9]
中級編:range関数の高度な活用法
逆順とマイナスステップ
# 逆順のrange
backward = list(range(10, 0, -1))
print(backward) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
# 偶数を逆順で
even_backward = list(range(20, 0, -2))
print(even_backward) # [20, 18, 16, 14, 12, 10, 8, 6, 4, 2]
# インデックスを逆順で処理
items = ['a', 'b', 'c', 'd', 'e']
for i in range(len(items)-1, -1, -1):
print(f"インデックス{i}: {items[i]}")
rangeオブジェクトの特性とメモリ効率
# rangeはイテレータオブジェクト
r = range(1000000)
print(type(r)) # <class 'range'>
print(len(r)) # 1000000
# メモリ効率的:実際の値は必要時に生成
import sys
print(f"range(1000000)のメモリ使用量: {sys.getsizeof(r)} bytes")
print(f"list(range(1000000))のメモリ使用量: {sys.getsizeof(list(r))} bytes")
# rangeオブジェクトのスライシング
sliced = r[100:110]
print(list(sliced)) # [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
上級編:range関数による高度なパターン処理
enumerate関数との組み合わせ
# データとインデックスを同時に処理
data = ['apple', 'banana', 'cherry', 'date']
# enumerate使用
for index, value in enumerate(data):
print(f"{index}: {value}")
# rangeとzipの組み合わせ(同等の処理)
for index, value in zip(range(len(data)), data):
print(f"{index}: {value}")
複雑なステップパターンの生成
def custom_range_pattern():
"""カスタムパターンの生成例"""
# フィボナッチ数列風のrange活用
a, b = 0, 1
for _ in range(10):
yield a
a, b = b, a + b
fib_like = list(custom_range_pattern())
print(fib_like) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
# 数学的パターンの生成
def geometric_sequence(start, ratio, count):
"""等比数列の生成"""
for i in range(count):
yield start * (ratio ** i)
geo_seq = list(geometric_sequence(2, 3, 5))
print(geo_seq) # [2, 6, 18, 54, 162]
二次元配列のインデックス処理
# 二次元リストの処理
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# 全要素の処理
for i in range(len(matrix)):
for j in range(len(matrix[i])):
print(f"[{i}][{j}] = {matrix[i][j]}")
# 対角線要素の取得
diagonal = [matrix[i][i] for i in range(len(matrix))]
print(f"対角線: {diagonal}") # [1, 5, 9]
難関編:range関数による高度なアルゴリズム実装
素数生成アルゴリズム(エラトステネスの篩)
def sieve_of_eratosthenes(limit):
"""エラトステネスの篩による素数生成"""
is_prime = [True] * (limit + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(limit**0.5) + 1):
if is_prime[i]:
# iの倍数をすべて合成数にマーク
for j in range(i*i, limit + 1, i):
is_prime[j] = False
return [i for i in range(2, limit + 1) if is_prime[i]]
primes = sieve_of_eratosthenes(50)
print(f"50以下の素数: {primes}")
組み合わせ・順列の生成
def generate_combinations(items, r):
"""組み合わせの生成(itertools.combinationsの簡易版)"""
if r == 0:
yield []
return
for i in range(len(items) - r + 1):
for combo in generate_combinations(items[i+1:], r-1):
yield [items[i]] + combo
# 使用例
items = ['A', 'B', 'C', 'D']
combinations = list(generate_combinations(items, 2))
print(f"2つ選ぶ組み合わせ: {combinations}")
def permutation_indices(n, r):
"""順列のインデックス生成"""
if r == 0:
yield []
return
for i in range(n):
for perm in permutation_indices(n, r-1):
if i not in perm:
yield [i] + perm
# 使用例
perm_indices = list(permutation_indices(4, 2))
print(f"順列インデックス: {perm_indices[:5]}") # 最初の5つ
数値解析での活用
def numerical_integration(func, start, end, steps=1000):
"""台形公式による数値積分"""
step_size = (end - start) / steps
total = 0
for i in range(steps):
x1 = start + i * step_size
x2 = start + (i + 1) * step_size
total += (func(x1) + func(x2)) * step_size / 2
return total
# 使用例:x^2の0から1までの積分
def square(x):
return x * x
result = numerical_integration(square, 0, 1, 10000)
print(f"∫x²dx (0→1) ≈ {result:.6f}") # 理論値: 1/3 ≈ 0.333333
エキスパート編:range関数による最適化技術
メモリ効率的な大規模データ処理
def process_large_dataset(size, chunk_size=1000):
"""大規模データセットのチャンク処理"""
for chunk_start in range(0, size, chunk_size):
chunk_end = min(chunk_start + chunk_size, size)
chunk_indices = range(chunk_start, chunk_end)
# チャンクごとの処理
chunk_data = process_chunk(chunk_indices)
yield chunk_data
def process_chunk(indices):
"""チャンクデータの処理例"""
return [i * 2 for i in indices]
# 使用例
total_size = 10000
for chunk in process_large_dataset(total_size, 500):
print(f"チャンク処理完了: {len(chunk)}個の要素")
if len(list(process_large_dataset(total_size, 500))) > 3: # 最初の数チャンクのみ表示
break
並列処理での範囲分割
import concurrent.futures
def parallel_range_processing(total_range, num_workers=4):
"""範囲を分割して並列処理"""
chunk_size = total_range // num_workers
def worker(start, end):
result = []
for i in range(start, end):
# 重い処理のシミュレーション
result.append(i ** 2)
return result
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
futures = []
for i in range(num_workers):
start = i * chunk_size
end = start + chunk_size if i < num_workers - 1 else total_range
future = executor.submit(worker, start, end)
futures.append(future)
# 結果の統合
all_results = []
for future in concurrent.futures.as_completed(futures):
all_results.extend(future.result())
return sorted(all_results)
# 使用例
# results = parallel_range_processing(1000)
# print(f"並列処理結果の最初の10個: {results[:10]}")
カスタムイテレータの実装
class CustomRange:
"""カスタムrange実装"""
def __init__(self, start, stop=None, step=1):
if stop is None:
self.start = 0
self.stop = start
else:
self.start = start
self.stop = stop
self.step = step
def __iter__(self):
current = self.start
while (self.step > 0 and current < self.stop) or \
(self.step < 0 and current > self.stop):
yield current
current += self.step
def __len__(self):
if self.step > 0:
return max(0, (self.stop - self.start + self.step - 1) // self.step)
else:
return max(0, (self.start - self.stop - self.step - 1) // (-self.step))
def __getitem__(self, index):
if isinstance(index, slice):
start, stop, step = index.indices(len(self))
return CustomRange(
self.start + start * self.step,
self.start + stop * self.step,
self.step * (step or 1)
)
else:
if index < 0:
index += len(self)
if 0 <= index < len(self):
return self.start + index * self.step
raise IndexError("CustomRange index out of range")
# 使用例
custom_r = CustomRange(5, 20, 3)
print(list(custom_r)) # [5, 8, 11, 14, 17]
print(custom_r[2]) # 11
print(list(custom_r[1:3])) # [8, 11]
range関数のパフォーマンス最適化
リスト内包表記での活用
import time
def performance_comparison():
"""パフォーマンス比較"""
n = 100000
# 方法1: 通常のforループ
start = time.time()
result1 = []
for i in range(n):
if i % 2 == 0:
result1.append(i * 2)
time1 = time.time() - start
# 方法2: リスト内包表記
start = time.time()
result2 = [i * 2 for i in range(n) if i % 2 == 0]
time2 = time.time() - start
# 方法3: filter + map
start = time.time()
result3 = list(map(lambda x: x * 2, filter(lambda x: x % 2 == 0, range(n))))
time3 = time.time() - start
print(f"forループ: {time1:.4f}秒")
print(f"リスト内包表記: {time2:.4f}秒")
print(f"filter + map: {time3:.4f}秒")
# performance_comparison()
ジェネレータ式との組み合わせ
def memory_efficient_processing():
"""メモリ効率的な処理例"""
# 大きな範囲でもメモリを節約
def squares_generator(n):
return (i ** 2 for i in range(n))
# 必要な分だけ処理
squares = squares_generator(1000000)
# 最初の10個だけ取得
first_ten = []
for i, square in enumerate(squares):
if i >= 10:
break
first_ten.append(square)
return first_ten
result = memory_efficient_processing()
print(f"最初の10個の平方数: {result}")
実践的なrange関数活用パターン
データ処理での応用
def analyze_data_chunks(data, window_size=5):
"""スライディングウィンドウでのデータ分析"""
results = []
for i in range(len(data) - window_size + 1):
window = data[i:i + window_size]
avg = sum(window) / len(window)
results.append(avg)
return results
# 使用例
sample_data = [1, 4, 7, 2, 8, 5, 9, 3, 6]
moving_averages = analyze_data_chunks(sample_data, 3)
print(f"移動平均: {moving_averages}")
def batch_process_items(items, batch_size=3):
"""アイテムのバッチ処理"""
for i in range(0, len(items), batch_size):
batch = items[i:i + batch_size]
print(f"バッチ {i//batch_size + 1}: {batch}")
yield batch
items = list(range(10))
batches = list(batch_process_items(items))
ゲーム開発での座標計算
def generate_grid_coordinates(width, height):
"""グリッド座標の生成"""
return [(x, y) for x in range(width) for y in range(height)]
def spiral_coordinates(size):
"""スパイラル状の座標生成"""
coordinates = []
x = y = 0
dx, dy = 1, 0
for _ in range(size * size):
coordinates.append((x, y))
# 境界チェックと方向転換
if (x + dx >= size or x + dx < 0 or
y + dy >= size or y + dy < 0 or
(x + dx, y + dy) in coordinates):
dx, dy = -dy, dx # 90度回転
x += dx
y += dy
return coordinates
# 使用例
grid = generate_grid_coordinates(3, 3)
print(f"3x3グリッド: {grid}")
spiral = spiral_coordinates(3)
print(f"スパイラル座標: {spiral}")
range関数の落とし穴と注意点
よくある間違いとその対策
# 間違い1: 浮動小数点でのrange使用
# range(0.5, 5.5, 0.5) # エラー!
# 正しい方法: 整数で計算後に変換
def float_range(start, stop, step):
"""浮動小数点のrange風関数"""
i = start
while i < stop:
yield i
i += step
float_values = list(float_range(0.5, 5.5, 0.5))
print(f"浮動小数点range: {float_values}")
# 間違い2: rangeオブジェクトの直接操作
# r = range(10)
# r.append(11) # エラー!rangeは変更不可
# 正しい方法: リストに変換
r_list = list(range(10))
r_list.append(11)
print(f"拡張されたリスト: {r_list}")
まとめ:range関数をマスターするためのポイント
Pythonのrange関数は、単純な反復処理から高度なアルゴリズム実装まで、幅広い場面で活用できる強力な機能です。その特性を深く理解することで、より効率的で読みやすいコードを書くことができます。
重要なポイント
- メモリ効率: rangeはイテレータオブジェクトでメモリ効率が良い
- 柔軟性: start, stop, stepパラメータによる柔軟な制御
- 最適化: リスト内包表記やジェネレータとの組み合わせ
- 応用範囲: 数値計算からデータ処理まで幅広い活用
実践での活用法
- データの分割・バッチ処理
- 数学的アルゴリズムの実装
- パフォーマンス最適化
- 座標計算や配列操作
継続的な練習と実践により、range関数を効果的に活用できるようになり、Pythonプログラミングスキル全体の向上につながります。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座