【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爆速講座