概要
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例外
-
list
やstr
はイテラブル(__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
を使えばなんでも繰り返せる?
→ ✅ for
は iter()
と next()
に依存しているため、明示的なイテラブルでなければ使えない
❌ next()
を直接呼ぶのは非推奨?
→ ✅ 開発者が意図的に状態制御したい場合はnext()の使用が適切
結語
イテラブル/イテレータ/イテレーション──
この3つの構造を理解することは、Pythonにおけるあらゆるループ構造・状態管理・遅延評価の基礎となる。
-
for
文は構文、iter()
/next()
はプロトコル - 状態を持たせた繰り返し処理の設計にはジェネレータが最適
- イテラブル/イテレータの分離は、設計の明快さと再利用性の鍵
Pythonicとは、“ループすらも構文として隠すことで、意図だけを残す”ことにあり、
イテラブルの理解は、その沈黙する力を最大限に引き出す第一歩である。