【Python】イテレータを知ってみる
Pythonにあるイテレータ(iterator)について書こうと思います。
存在は知っていましたが、使ったことがなかったのでよく知らない機能でした。
外出自粛中なので、これを機に使いこなせるようになろうと調べました。
イテレータ
反復して要素を取り出すことのできるインターフェイス
また、イテレータ化されたオブジェクトをイテレータオブジェクトと呼ぶそうです。
特徴
- オブジェクトのイテレータ化には
__iter__()
メソッドが必要 - イテレータオブジェクトは
__next__()
メソッドが呼ばれる度に新しい値(次の値)を返す __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を書いている人の多くが意識せずに使っているものでした。
次は、よく出てくるジェネレータについて調べたいと思ってます。。
では!