1. はじめに|イテレーターとジェネレーターってなに?
Pythonでプログラムを書いていると、「たくさんのデータを1つずつ順番に処理したい!」という場面によく出会います。たとえば、長〜いリストや大量のファイルの行を、1つずつ順番に取り出して使いたいときってありますよね?
そんなときに登場するのが「イテレーター(iterator)」と「ジェネレーター(generator)」です。
✅ イテレーターとは?
イテレーターは、リストや文字列のような「たくさんのデータの集まり」を、順番に1つずつ取り出せる仕組みのことです。
たとえば、以下のようなfor文を書いたことがある人も多いはず。
for item in ["りんご", "みかん", "バナナ"]:
print(item)
これ、実は裏側ではイテレーターが使われていて、リストから1個ずつデータを取り出して処理しているんです!
✅ ジェネレーターとは?
一方でジェネレーターは、「自分で作れるカスタムイテレーター」のようなもの。yield(イールド)というキーワードを使うことで、関数の中から1つずつデータを返せるんです。
普通の関数はreturnで1回だけ値を返して終わりますが、ジェネレーターはyieldを使うことで、何度でも値を返しながら動き続けることができます。
✅ この記事でわかること
この記事では、イテレーターとジェネレーターの違いを初心者向けにやさしく解説していきます。
- 「イテレーターってどうやって作るの?」
- 「ジェネレーターって何が便利なの?」
- 「for文で使えるのはどうして?」
こんな疑問を解決しながら、実際のコード例を交えて学べる内容になっています。
「メモリを節約しながらスマートにデータを扱いたい!」という方にもぴったりな内容なので、ぜひ最後まで読んでみてくださいね!
2. イテレーターとは?仕組みと基本の使い方
Pythonでよく使うfor文って、実は「イテレーター」という仕組みを使って動いているって知ってましたか?
この章では、イテレーターの基本をわかりやすく紹介していきます!
✅ イテレーターってなに?
イテレーターは、データを1つずつ順番に取り出せるしくみのことです。
たとえば、リストやタプルなど、いろんなデータが集まっているもの(これをイテラブルっていいます)から、順番に1個ずつ値を取り出して処理するために使います。
fruits = ["りんご", "みかん", "バナナ"]
for fruit in fruits:
print(fruit)
↑このコード、実は裏で「イテレーター」がこっそり動いています。
✅ next()関数を使って取り出す
実は、for文を使わなくても、next()という関数を使えば、イテレーターから自分のタイミングで1個ずつデータを取り出すこともできます。
fruits = ["りんご", "みかん", "バナナ"]
it = iter(fruits) # イテレーターを作る
print(next(it)) # → りんご
print(next(it)) # → みかん
print(next(it)) # → バナナ
print(next(it)) # → エラー!(データがもうないよ)
最後のnext(it)はデータが無くなっているので、「StopIteration」というエラーになります。
✅ イテレーターの正体(ちょっとだけ専門的な話)
Pythonでは、あるオブジェクトがイテレーターであるために、2つの“特別な関数”を持っている必要があります。
| 特別な関数 | 役割 |
|---|---|
__iter__() | 自分自身を返す |
__next__() | 次の要素を返す(無くなったらエラー) |
class MyIterator:
def __init__(self):
self.data = [1, 2, 3]
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
こんなふうに自分でクラスを作れば、自作のイテレーターも作れちゃうんです!
✅ ファイルオブジェクトもイテレーター!
Pythonでファイルを読み込むとき、for文で1行ずつ処理できますよね?
with open("data.txt") as f:
for line in f:
print(line.strip())
これは、ファイルオブジェクトが最初からイテレーターになっているからです!
大量のテキストデータを扱うときに、1行ずつ読み込めるのでメモリ節約にもなります。
✅ イテレーターの注意点
イテレーターは一度使い切ったらもう使えません!
it = iter([1, 2, 3])
for num in it:
print(num) # 1, 2, 3 が出力される
for num in it:
print(num) # 何も出力されない

このように、一度取り出したデータは「消費された」とみなされて、再び取り出すことはできません。
何度も繰り返したいなら、リストのまま使うか、イテレーターを新しく作り直す必要があります。
3. ジェネレーターとは?yieldで簡単にイテレーターを作ろう
前の章で、イテレーターを自分で作るには__iter__()や__next__()を定義する必要があると説明しましたね。でも、実はもっと簡単にイテレーターを作る方法があるんです。
それが、今回紹介する「ジェネレーター」です!
✅ ジェネレーターってなに?
ジェネレーターは、yield(イールド)というキーワードを使って値を順番に返す関数のことです。
yieldを使うと、関数の実行を途中で一時停止しながら、値を1つずつ返していくことができます。
なんだかむずかしそうに聞こえますが、実はめちゃくちゃ簡単なんです!
✅ yieldの基本的な使い方
まずは例を見てみましょう👇
def my_generator():
yield 1
yield 2
yield 3
この関数を呼び出すと、普通の値ではなく「ジェネレーターオブジェクト」が返されます。
gen = my_generator()
print(next(gen)) # → 1
print(next(gen)) # → 2
print(next(gen)) # → 3
print(next(gen)) # → StopIteration(データがないよ)
このように、yieldで1つずつ値を返していき、呼び出すたびに「続きを実行」してくれるのがジェネレーターです。
✅ 普通の関数(return)との違い
| 比較ポイント | return | yield |
|---|---|---|
| 処理の流れ | その場で関数を終了 | 処理を一時停止 |
| 呼び出し結果 | 値を返して終了 | イテレーターを返す |
| 使える回数 | 一度きり | 何度でもnext()で続きが実行できる |
つまり、yieldを使えば「分割して値を返せる関数」を作れるんです!
✅ for文でもそのまま使える
ジェネレーターオブジェクトもイテレーターなので、for文でそのまま使うことができます。
def count_up_to(max):
num = 1
while num <= max:
yield num
num += 1
for i in count_up_to(3):
print(i)
# → 1
# → 2
# → 3
こんな感じで、普通の関数みたいに呼び出せるのに、実はメモリを節約しながらデータを1つずつ取り出せるのがポイントです!
✅ ジェネレーターを使うメリット
- コードがシンプルになる
→__iter__()や__next__()を自分で書かなくていい! - メモリを節約できる
→ 全部のデータを一気に持たなくても、1つずつ生成できる! - 大きなデータも安心して扱える
→ 100万行のデータも、1行ずつ読み込める!
✅ ジェネレーターを使うときの注意点
- 一度処理が終わったジェネレーターは使いまわしできません。
- 途中の状態を保持しているので、実行の順番を変えることはできません。
- デバッグが少し難しく感じるかもしれません。

でも、それを上回るほど便利な場面がたくさんあるので、ぜひ使いこなしてみましょう!
4. イテレーターとジェネレーターの違いと使い分け
ここまで読んできた方は、「イテレーターとジェネレーターって、似てるけどどう違うの?」と思っているかもしれません。
この章では、両者の違いをわかりやすく表にまとめて比較し、さらにどう使い分ければいいのかをやさしく解説します!
✅ 違いを表で比べてみよう!
| 比較ポイント | イテレーター | ジェネレーター |
|---|---|---|
| 正体 | 特殊メソッドを持ったオブジェクト (__iter__ と __next__) | yieldを使った関数で作られたオブジェクト |
| 実装方法 | クラスで__iter__と__next__を定義 | 関数にyieldを書く |
| コード量 | やや多い(クラス定義が必要) | 少ない(関数だけでOK) |
| メモリ効率 | よい(1つずつ取り出す) | とてもよい(遅延評価ができる) |
| for文との相性 | ◎ | ◎ |
| 状態の保存 | 自分で管理する必要あり | Pythonが自動で保存してくれる |
| 再利用 | できない(1回使い切り) | できない(1回使い切り) |
✅ 使い分けの目安
どちらも「データを1つずつ取り出す」という目的は同じですが、使いやすさや書きやすさに違いがあります。
✔ クラスのように複雑な状態管理が必要なら「イテレーター」
# 例:複数のリストをまたいでデータを出すような高度な処理
✔ シンプルに順番に値を返したいなら「ジェネレーター」
def countdown(n):
while n > 0:
yield n
n -= 1
✅ 初心者におすすめなのは?
初心者さんには、まずはジェネレーターを使うのがおすすめ!
理由は…
- コードが短くてわかりやすい
for文との相性がバツグンyieldだけ覚えればすぐ使える
「イテレーターをクラスで書く」のは、もう少しPythonに慣れてからでもOKです!
✅ 補足:ジェネレーター式(Generator Expression)
さらに一歩進んだテクニックとして、「ジェネレーター式」という書き方もあります。
gen = (x * 2 for x in range(5))
print(next(gen)) # → 0
見た目はリスト内包表記と似ていますが、カッコ () を使うことでメモリを使わずに1つずつ生成できるのがポイントです。

こちらも便利なので、興味があればあとで詳しく解説します!
5. 応用例|自作ジェネレーター関数でデータを1万件扱う
ここでは、実際に大量のデータ(1万件)を扱うジェネレーター関数を作ってみましょう!
「そんなにいっぱいのデータ、どうやって処理するの?」と心配になるかもしれませんが…
ジェネレーターを使えば、メモリをほとんど使わずにラクラク処理できちゃいます!
✅ 普通に1万件のリストを作るとどうなる?
たとえば、こんなコードを書いてみると…
numbers = [i for i in range(10000)]
print(numbers[9999])
リストはとても便利ですが、すべての値を一度にメモリに保存するので、大きなデータになるとパソコンのメモリをたくさん使ってしまいます。
✅ ジェネレーターで1万件を1つずつ取り出してみよう!
ジェネレーターを使えば、データを必要なときにだけ1つずつ作り出すことができます。
def generate_numbers():
for i in range(10000):
yield i
この関数を使ってみましょう!
gen = generate_numbers()
for num in gen:
if num % 1000 == 0:
print(f"{num} 件目のデータ処理中...")
このコードは、1件ずつデータを処理していて、しかも1,000件ごとに進捗(しんちょく)を表示します。
全部をメモリにためていないので、軽くてスピーディー!
✅ これができると何が便利なの?
- 大量のファイル処理(1行ずつログを読むとか)
- Webスクレイピング(ページを順番に処理するとき)
- データベースからの逐次読み込み(一括取得せず小分けに)
…などなど、現実のプログラミングでもよく使われています!
✅ 応用のヒント:フィルター付きジェネレーター
さらに少し発展すると、「条件に合ったデータだけを返すジェネレーター」も作れます。
def even_numbers(max_num):
for i in range(max_num):
if i % 2 == 0:
yield i
for num in even_numbers(20):
print(num)
このコードでは、0〜19の中で偶数だけを取り出して表示しています。

たくさんのデータを1つずつ処理したいとき、ジェネレーターはとても頼れる存在です。
今回のように「1万件のデータを軽く処理できる」のは、まさにジェネレーターの強みですね!
6. まとめ|イテレーター・ジェネレーターでPythonをもっと効率的に
ここまで、Pythonの「イテレーター」と「ジェネレーター」について学んできました。
ちょっとむずかしそうな言葉でしたが、だんだんイメージできてきたのではないでしょうか?
この章では、これまでのポイントをふり返って、最後に整理してみましょう!
✅ イテレーターとは?
- リストやファイルなど、たくさんのデータを1つずつ取り出す仕組み。
next()で順番に取り出せて、取り出し終わるとStopIterationエラーが出る。- ファイルや
for文の中でもよく使われている。
✅ ジェネレーターとは?
yieldを使って簡単にイテレーターを作れる関数。- 関数の途中で「一時停止」できて、
next()で再開する。 for文でもそのまま使えて、メモリを節約しながら大きなデータも扱える!
✅ こんなときに使うと便利!
| やりたいこと | おすすめ |
|---|---|
| クラスで複雑な処理をカスタムしたい | イテレーター(__iter__, __next__) |
| シンプルに1つずつ値を出したい | ジェネレーター(yield) |
| 大量のデータを軽く処理したい | ジェネレーター |
| データをフィルターしながら処理したい | ジェネレーター+条件式 |
✅ Pythonをもっと効率よく書くために
Pythonには、こういった「スマートに動くしくみ」がたくさんあります。
イテレーターやジェネレーターを使いこなせるようになると、シンプルで読みやすい、そして動作が軽いプログラムが書けるようになります!
📝 次におすすめの記事は?
このあと読みたい関連記事を以下にご紹介します👇
- 🔗 【Python入門】while文の使い方とbreak・continueの違い
- 🔗 Pythonのセイウチ演算子とは?代入式「:=」の使い方
- 🔗 初心者でもすぐわかる!Pythonのクラス入門ガイド
難しそうに見える「イテレーター」や「ジェネレーター」も、実はPythonの中ではとてもよく使われている便利な仕組みです。
少しずつ練習しながら、自分のコードにも取り入れてみましょう!
「一気に全部処理」じゃなくて、「1つずつ丁寧に処理」。
それが、プログラムでも人間関係でも大事なことかもしれませんね😊
よくある質問(Q&A)
- Qイテレーターとイテラブルって何が違うの?
- A
「イテラブル」は
for文で使えるオブジェクト(リスト・文字列・辞書など)のことです。
「イテレーター」はそのイテラブルから1つずつ値を取り出すためのしくみです。イテラブル → イテレーターに変換 → 1つずつ取り出し
という流れになります。
- Q
yieldとreturnの違いってなに? - A
returnは値を返したらそこで関数が終わりますが、yieldは値を返して関数の実行を一時停止できます。
次にnext()が呼ばれると、途中からまた再開できるのがyieldの特徴です。
- Qイテレーターやジェネレーターは何回でも使えますか?
- A
いいえ、一度使い終わったら再利用はできません。
もう一度使いたい場合は、新しく作り直す必要があります。







※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。
※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。