イテラブルとイテレータ

INPUT · スライド

for を手で再現する

01 / 07

係を自分でもらう

前のレッスンに出てきた「1つずつ配る係」を、自分でもらってみよう。使うのは iter(イター)。イテラブルを渡すと、イテレータが返ってくるよ。

kudamonos = ["りんご", "みかん"]it = iter(kudamonos)print(it)<list_iterator object at 0x1234abcd>

it という名前は iterator の頭だけを取ったもの。Pythonのコードでよく見かける書きかただよ。

02 / 07

next で次の値をもらう

もらった係に「次の値をくれ」と頼むのが next(ネクスト)。呼ぶたびに、次の1つが返ってくるよ。

同じ next(it) を3回書いているのに、毎回ちがう値が出るところに注目してほしい。イテレータが「どこまで配ったか」を覚えているんだ。

kudamonos = ["りんご", "みかん", "ぶどう"]it = iter(kudamonos)print(next(it))print(next(it))print(next(it))

実行結果

りんご
みかん
ぶどう

03 / 07

使い切ると怒られる

中身が1つしか無いのに2回目を頼むとどうなるか。StopIteration というエラーになるよ。

名前のとおり「くり返しはここで止まり」という合図だ。for はこの合図を受け取って、静かにループを終えていたんだね。

it = iter(["りんご"])print(next(it))print(next(it))

実行結果

りんご
StopIteration

04 / 07

既定値を渡せば止まらない

next には2つめの引数を渡せる。もう無いときに代わりに返す値だよ。

next(it, "おわり") と書けば、使い切ってもエラーにならず おわり が返ってくる。エラーを受け止める書きかたを足さずに済むので、覚えておくと便利だよ。

it = iter(["りんご"])print(next(it, "おわり"))print(next(it, "おわり"))

実行結果

りんご
おわり

05 / 07

for を手で書き直す

ここまでの道具で、for と同じことが書ける。イテレータをもらって、無くなるまで頼み続けるだけだ。

下のコードと for kudamono in kudamonos: は、まったく同じことをしている。長いぶんだけ、中で何が起きているかがよく見えるね。

kudamonos = ["りんご", "みかん"]it = iter(kudamonos)tsugi = next(it, None)while tsugi is not None:    print(tsugi)    tsugi = next(it, None)

実行結果

りんご
みかん

06 / 07

イテレータは戻れない

ひとつ大事な性質がある。イテレータは使い切ると、もう一度は回せない。巻き戻すことができないんだ。

下の例では、2回目の for から何も出てこない。イテレータはもう配り終わっているからだよ。

何度でも回したいなら、回す相手はリストのほうにすること。リストは頼まれるたびに新しい係を作ってくれるよ。

it = iter(["りんご", "みかん"])for kudamono in it:    print(kudamono)print("2かいめ")for kudamono in it:    print(kudamono)print("おわり")

実行結果

りんご
みかん
2かいめ
おわり

07 / 07

まとめ

for の正体はこうだった。

  • iter でイテレータをもらう
  • next で次の値をもらう
  • StopIteration が来たら終わる

もう魔法ではないね。ふだんは for を書けばいいけれど、中身を知っていると説明書が読めるようになる。

次のレッスンからは、毎日使う道具を2つ覚えるよ。ここからが実用の話だ。