2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonにおけるイテラブル・イテレータ・イテレーションの完全理解

Posted at

概要

Pythonの for 文、リスト内包表記、ジェネレータ、next()iter()──
これらはすべて「イテレーションプロトコル」に基づいて動作している。

だがこの背後には、イテラブルとイテレータという明確に区別された2つの概念が存在する。
本稿では、Pythonの反復処理を支えるこの構造の違い・実装・設計意図を明快に整理する。


1. イテラブル vs イテレータ:定義と違い

用語 意味
イテラブル __iter__() メソッドを持つオブジェクト
イテレータ __iter__() + __next__() を持つオブジェクト

✅ すべてのイテレータはイテラブル

❌ すべてのイテラブルがイテレータとは限らない


2. 実例による違いの可視化

data = [10, 20, 30]

it = iter(data)           # イテラブル → イテレータ化
print(next(it))           # → 10
print(next(it))           # → 20
print(next(it))           # → 30
# print(next(it))         # StopIteration例外
  • liststr はイテラブル(__iter__()を持つ)
  • iter() を使うことで明示的にイテレータを取得

3. for 文の裏側で何が起きているのか?

for item in data:
    process(item)

上記は以下と等価:

it = iter(data)
while True:
    try:
        item = next(it)
        process(item)
    except StopIteration:
        break

for 文は イテレータプロトコル を自動で呼び出している構文的シュガー


4. 自作クラスをイテラブルにする

class MyRange:
    def __init__(self, stop):
        self.stop = stop

    def __iter__(self):
        return MyRangeIterator(self.stop)

class MyRangeIterator:
    def __init__(self, stop):
        self.i = 0
        self.stop = stop

    def __iter__(self):
        return self

    def __next__(self):
        if self.i >= self.stop:
            raise StopIteration
        val = self.i
        self.i += 1
        return val

MyRange はイテラブル、MyRangeIterator はイテレータ
→ 明確な役割分担による 再利用性と拡張性 の確保


5. ジェネレータ関数・式の設計的利点

def countdown(n):
    while n > 0:
        yield n
        n -= 1
for i in countdown(3):
    print(i)  # → 3 2 1

→ ジェネレータは 状態を自動的に保持するイテレータ を構築する
→ イテレータクラスの記述を不要にする、Pythonicな構文的圧縮


6. 実務的ユースケース

✅ ストリーム処理(ファイル・APIレスポンスなど)

with open("log.txt") as f:
    for line in f:
        parse(line)

open()イテラブルなファイルオブジェクト を返す


✅ ラップ処理によるロジック追加

def logged_iter(iterable):
    for item in iterable:
        print(f"yielding: {item}")
        yield item

→ 既存のイテラブルに副作用を追加しつつ、イテレータとして再利用


7. よくある誤解と対策

❌ イテラブル=リストだけ?

→ ✅ タプル、辞書、集合、文字列、ファイル、range、map、filter、ジェネレータ…すべてイテラブル


for を使えばなんでも繰り返せる?

→ ✅ foriter()next() に依存しているため、明示的なイテラブルでなければ使えない


next() を直接呼ぶのは非推奨?

→ ✅ 開発者が意図的に状態制御したい場合はnext()の使用が適切


結語

イテラブル/イテレータ/イテレーション──
この3つの構造を理解することは、Pythonにおけるあらゆるループ構造・状態管理・遅延評価の基礎となる。

  • for 文は構文、iter()/next() はプロトコル
  • 状態を持たせた繰り返し処理の設計にはジェネレータが最適
  • イテラブル/イテレータの分離は、設計の明快さと再利用性の鍵

Pythonicとは、“ループすらも構文として隠すことで、意図だけを残す”ことにあり、
イテラブルの理解は、その沈黙する力を最大限に引き出す第一歩である。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?