Pythonのジェネレーターをやさしく解説!初心者でもわかるyieldとイテレーターの基本
生徒
「Pythonのジェネレーターって聞いたんですが、なんですか?難しそうです…」
先生
「ジェネレーターは、大量のデータを一つずつ順番に取り出せる便利なしくみですよ。使い方も簡単なんです。」
生徒
「それってfor文と何が違うんですか?」
先生
「とても良い質問です。for文で全部まとめて処理する代わりに、ジェネレーターでは一つずつ処理できるんです。少しずつ一緒に学んでいきましょう!」
1. ジェネレーターとは?Pythonのyieldの意味を解説
Python(パイソン)には、ジェネレーター(generator)という特別な関数があります。これは、一度に全部の結果を出すのではなく、必要なときに一つずつ値を返す関数です。
普通の関数ではreturnで結果を返しますが、ジェネレーターではyield(イールド)を使います。
yieldは「一時停止して、次に呼ばれたときにまた再開する」という動き方をします。
2. ジェネレーターを使うと何が便利なの?
- 大量のデータを一気にメモリに読み込まない
- データを一つずつ処理できるから軽くて速い
- for文と似たように書けるので初心者にも扱いやすい
たとえば100万件のデータを全部リストにすると、パソコンのメモリがいっぱいになります。でも、ジェネレーターなら1つずつ処理するので、省メモリで安全です。
3. 簡単なジェネレーター関数を作ってみよう
数字を1から3まで順番に返す簡単なジェネレーターを書いてみましょう。
def number_generator():
yield 1
yield 2
yield 3
このnumber_generator関数は、呼ばれるたびにyieldで値を1つずつ返します。次に、どうやって呼び出すかを見てみましょう。
4. ジェネレーターの使い方(呼び出し方)
ジェネレーター関数を使うには、next()関数を使います。
gen = number_generator()
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
1
2
3
このように、next()を呼ぶたびにyieldが1つずつ実行されます。
そして最後まで行くとStopIterationというエラーが出ます。これは「もう返すものがありませんよ」というサインです。
5. for文でジェネレーターを使う
for文でもジェネレーターを簡単に使えます。次のように書くと、全部順番に取り出してくれます。
for num in number_generator():
print(num)
1
2
3
初心者でも書きやすく、見た目もスッキリしています。
6. イテレーターとの違いと関係
Pythonでは、イテレーター(iterator)という「順番に取り出せるもの」があります。リストや文字列もイテレーターにできます。
ジェネレーターは、イテレーターを作る簡単な方法です。次のように言えます:
- イテレーター:順番に取り出せるもの(例:リスト)
- ジェネレーター:自分で作れるイテレーター(
yieldを使う)
実際にジェネレーター関数から作られたものは、イテレーターの仲間です。
7. ジェネレーターの中にループを書くとどうなる?
yieldは、ループと一緒に使うこともできます。たとえば、1から5までの数字を順番に返したいときはこう書きます。
def count_up():
for i in range(1, 6):
yield i
for num in count_up():
print(num)
1
2
3
4
5
このように、forの中でyieldを使えば、もっと便利に繰り返しができます。
8. ジェネレーターとリストの違いを比べてみよう
次のように、ジェネレーターとリストの違いを比べてみましょう。
# リストの場合
numbers = [i for i in range(1000000)]
# ジェネレーターの場合
def generate_numbers():
for i in range(1000000):
yield i
リストは最初からすべて作っておくので、メモリをたくさん使います。一方、ジェネレーターは必要な分だけ作るので、メモリを節約できます。
9. ジェネレーターの注意点
- 一度使い切ると、もう一度使えない
returnではなく、yieldを使うyieldが関数の中にあると、その関数はジェネレーターになる
一度for文やnext()で全部読み終わったジェネレーターは、もう使えないので注意しましょう。
10. 実践:偶数だけを返すジェネレーター
最後に、1から10までの偶数だけを返すジェネレーターを作ってみましょう。
def even_numbers():
for i in range(1, 11):
if i % 2 == 0:
yield i
for num in even_numbers():
print(num)
2
4
6
8
10
このように、if文とyieldを組み合わせることで、条件をつけて値を返すことができます。