当サイトは、アフィリエイト広告を利用しています

【Python】イテラブル・イテレータ・ジェネレータの違いを整理する

作成日:2026月02月21日
更新日:2026年03月06日

Pythonの反復処理は、一見するとfor文だけで完結しているように見える。
しかし内部では明確な構造が存在する。

  • イテラブル(Iterable)
  • イテレータ(Iterator)
  • ジェネレータ(Generator)

これらは別物である。
混同しやすいが、関係性は階層構造になっている。

全体構造
Iterable
└── Iterator
└── Generator
  • ジェネレータはイテレータの一種
  • イテレータはイテラブルから生成される

また前提として、for文は内部的下記の構造で動いてる

pythonの反復モデル
it = iter(obj)
while True:
try:
value = next(it)
except StopIteration:
break

この仕組みを理解すると

  • イテラブル(Iterable)
  • イテレータ(Iterator)
  • ジェネレータ(Generator)

を理解することができる

当記事では

  • イテラブルとは何か
  • イテレータとは何か
  • ジェネレータとは何か
  • yieldの役割
  • 遅延評価との関係

について、反復モデルの内部構造という観点から整理する。

イテラブル(iterable)とは?

イテラブルとは反復可能なオブジェクトのこと。
具体的には

  • list: [1, 2, 3]
  • tuple: (1, 2, 3)
  • set: {1, 2, 3}
  • dict: {1: "A", 2: "B", 3: "C"}
  • str: "ABC"

といった反復可能なオブジェクトがイテラブルとなる。

特徴

  • for文で回すことができる
  • 自身で値を返す機能は持たない
  • iter()を呼ぶとイテレータを返す

つまりイテラブルは「材料」のこと

イテラブルに関する詳細は下記記事参照

イテレータ(iterator)とは?

イテレータとは、イテラブルから生成される値を1つずつ返すオブジェクトである。
listを例にして説明すると

イテレータの例
# イテラブル生成
list = [1, 2, 3]
# iter()を呼ぶとイテレータを返す
it = iter(list)
# イテレータから値を取得(next)
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
print(next(it)) # StopIteration
# イテラブル作成
tuple = (1, 2, 3)
# iter()を呼ぶとイテレータを返す
it = iter(tuple)
# イテレータから値を取得(for文)
for value in it:
print(value) # 1
# 2
# 3
  • iter()を呼ぶとイテレータを返す
  • next()を呼ぶと値を返す
  • 末尾まで到達したらStopIteration例外を発生させる
  • 一方方向にしか進めない

イテレータは「順に値を返す仕組み」である。
※イテレータ自体は遅延評価ではない

イテレータに関してさらに深く解説した記事は下記参照

ジェネレータ(generator)とは?

yieldによって作られるイテレータのこと。
つまりジェネレータはイテレータの一種である。 ※ジェネレータはイテレータに含まれる

ジェネレータの生成方法は

  • ジェネレータ関数
  • ジェネレータ式

の2種類ある

ジェネレータ関数

ジェネレータ関数
def generator():
yield 1
yield 2
yield 3
  • yieldを含む関数を作る→ジェネレータ関数
  • ジェネレータ関数を呼ぶとジェネレータを返す

ジェネレータ式

ジェネレータ式
generator = (value for value in list([1, 2, 3]))
  • ジェネレータ式という構文
  • ジェネレータ式はコンパイル時にジェネレータ関数相当へ変換される

yieldとは?

yieldは

  • 値を返す
  • そこで停止
  • 状態を保持
  • next()で再開

のように必要になった瞬間にだけ進む構造を実現する。

yield を含む関数はジェネレータ関数となり、
呼び出すとジェネレータ(イテレータ)を返す。

ジェネレータは next() が呼ばれたときにのみ処理を再開し、次の yield まで実行される。
つまり処理は「必要になった瞬間」にだけ進む逐次実行モデルを持つ。

この実行モデルにより、計算の評価が next() 呼び出し時まで延期される。
これを遅延評価(lazy evaluation)と呼ぶ。

なお、遅延評価はイテレータの定義そのものではない。
イテレータは単に「次の値を返す仕組み」であり、
ジェネレータはその中でも遅延評価を代表的に実現するイテレータである。
※イテレータはあくまで取り出し方の仕組み

遅延評価という概念

遅延評価とは、

  • 値が実際に必要になるまで計算を実行しない評価戦略のこと。

Pythonではジェネレータが代表例である。

通常のリスト(即時評価)

通常のリスト
# イテレータ生成
lst = [x for x in [1, 2, 3]]
print(lst) # [1, 2, 3]

このコードではリスト内包表記が実行された瞬間に
すべての要素が計算され
メモリ上にリストが生成される

つまり、必要になる前に全要素を生成、評価している(即時評価)

ジェネレータ(遅延評価)

ジェネレータ
# ジェネレータ生成
gen = (x for x in [1, 2, 3])
print(gen) # <generator object ...>
  • この時点ではまだ、要素の評価はまだ行われていない
  • ただ「計算方法(実行ロジック)」が保存されているだけ
  • 値を生成する“仕組み”を作っているイメージ
遅延評価
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
  • next()が呼ばれたタイミングで初めて式が評価される
  • このように評価が必要になるまで延期されることを遅延評価という

なお、この例では元のリスト [1,2,3] は即時に生成されている。
遅延しているのは内包式の評価部分である。

たとえば下記のような場合は、より遅延的な構造になる。

遅延生成
gen = (x for x in range(10**9))
  • range は巨大なリストを生成せず、値を順次計算する軽量なオブジェクトである
  • ジェネレータ式も next() が呼ばれるまで評価を行わない

このように、元データと評価処理の両方が逐次的に進む構造を持つと、
より「完全な遅延評価」に近い動作となる。

遅延評価は「構造の連鎖」で決まる。

  • 即時データ(list) × ジェネレータ → 評価のみ遅延(部分的遅延)
  • 逐次データ(range, ファイル, ジェネレータ) × ジェネレータ → データ取得と評価の両方が逐次実行(より遅延的)

ジェネレータの有効活用の具体的な方法については下記記事でまとめている

まとめ

Pythonの反復処理は

  • データを保持する構造(Iterable)
  • 値を取り出す仕組み(Iterator)
  • 状態を保持しながら生成する仕組み(Generator)

という役割分担の上に設計されている。

for 文は構文であり、その背後にはこの反復モデルが存在している。

関連記事

新着記事

タグ一覧
top