プログラマーの徒然ブログ

プログラミングに関することをはじめ、興味がでたものを雑多に!

【Python】イテレータを知ってみる

Pythonにあるイテレータiterator)について書こうと思います。

存在は知っていましたが、使ったことがなかったのでよく知らない機能でした。

外出自粛中なので、これを機に使いこなせるようになろうと調べました。

イテレータ

反復して要素を取り出すことのできるインターフェイス

また、イテレータ化されたオブジェクトをイテレータオブジェクトと呼ぶそうです。

特徴

  1. オブジェクトのイテレータ化には__iter__()メソッドが必要
  2. イテレータオブジェクトは__next__()メソッドが呼ばれる度に新しい値(次の値)を返す
  3. __next__()メソッドは、最後の値を返したあとStopIteration例外を返すようになる
    • 自作するときは、終了条件を作成するときはStopIterationを返すように作ること

__iter__()メソッドをもつオブジェクト例

Pythonの既存オブジェクトの中で、以下のオブジェクトは__iter__()メソッドを持ちます。 代表例なので、他にもあると思います。

  • list
  • tuple
  • set
  • dict

確認方法:イテレータオブジェクトか?

オブジェクトをobjとすると、下記のコードで確認することができます。

 hasattr(obj, '__iter__')

イテレータオブジェクトは何ができる?

ここが一番知りたいところかと思います。 しかし、多くの人が使っているんです。

最たるものが、次の例です。

例:forループ + リスト

nums = list((1,2,3))

for i in nums:
    print(i)

結果

1
2
3

上記例のように、for _ in リストの形式でforループをよく作るんじゃないでしょうか?

これが、イテレータオブジェクトを使っている例です。

forループに入るときに、リストのnumsからイテレータオブジェクトが生成されます。

イテレータオブジェクトに対して__next__()を繰り返して、要素を一つずつ取り出します。

そして、StopIteration例外の発生でforループを終了します。

この例を__iter__()メソッドと__next__()メソッドを明にして書くと、以下のコードになります。

nums = [1,2,3]

nums_iter = nums.__iter__()
while True:
    try:
        tmp = nums_iter.__next__()
    except StopIteration:
        break
    print(tmp)

結果

1
2
3

明に書くと、__iter__()メソッドと__next__()メソッドの意味が分かりやすくなったでしょうか? しかし、例外処理が必要になるのでコードが長くなってしまいます。 forループ+リストを使ったほうが簡潔で読み易いです。

そのほかに、イテレータオブジェクトが潜んでいそうな場所

  • 集合を扱う関数(set, max, .. etc)

forループの例以外にも、集合内の最大値を算出するmax関数などは、引数のオブジェクトをイテレータ化し処理を実行します。

つまり、イテレータ化できるようにした自作のオブジェクトも渡すことができます。


今回はここまで。

イテレータPythonを書いている人の多くが意識せずに使っているものでした。

次は、よく出てくるジェネレータについて調べたいと思ってます。。

では!