Python のイテラブルとイテレータの違い

Python では「イテラブル」と「イテレータ」という似た言葉がありますが、これらは明確に異なる概念です。混同しやすいので、しっかり整理しておきましょう。

イテラブルとは

イテラブル(iterable)とは、for 文で繰り返し処理できるオブジェクトのことです。リスト、タプル、文字列、辞書、集合などが該当します。

# これらはすべてイテラブル
for x in [1, 2, 3]:       # リスト
    print(x)

for c in "hello":          # 文字列
    print(c)

for k in {"a": 1, "b": 2}: # 辞書
    print(k)

イテラブルは __iter__() メソッドを持っており、これを呼び出すとイテレータを返します。

イテレータとは

イテレータ(iterator)とは、__next__() メソッドを持ち、要素を1つずつ取り出せるオブジェクトです。イテレータ自身も __iter__() を持っているため、イテラブルでもあります。

numbers = [1, 2, 3]
iterator = iter(numbers)  # イテレータを取得

print(next(iterator))  # 1
print(next(iterator))  # 2
print(next(iterator))  # 3

両者の関係

イテラブル

__iter__() を持つ。for 文で使える。何度でも繰り返せる。リスト、文字列、辞書など。

イテレータ

__iter__()__next__() を持つ。要素を1つずつ返す。一度使い切ると終わり。

重要なのは、イテラブルは「イテレータを生成できるもの」であり、イテレータは「実際に要素を取り出す機能を持つもの」という点です。

numbers = [1, 2, 3]

# イテラブルは何度でもイテレータを生成できる
iter1 = iter(numbers)
iter2 = iter(numbers)

print(next(iter1))  # 1
print(next(iter2))  # 1(別のイテレータなので最初から)

この違いを理解しておくと、for 文の動作やジェネレータの仕組みがより明確になります。