Pythonのiterator
とは
-
iterator
とは、可算量のvalueからなるオブジェクトです。 - Pythonでは
iterator
はiterator protcol
を実装したオブジェクトであり、__iter__()
と__next__()
メソッドからなります。 -
List
,Tuple
,Dict
,Set
などはいずれもiterable
なコンテナであるため、iter
,next
メソッドを持ちます。(明示していないだけでメソッドを含む)
例
class Line:
__start: Point
__end: Point
__next: Point
__direction: Direction
...
def __iter__(self) -> Iterator[Point]:
self.__next = self.__start
return self
def __next__(self) -> Point:
if self.__next == self.__end:
raise StopIteration
current = self.__next
self.__next = Point(
self.__next.x + self.__direction.x, self.__next.y + self.__direction.y
)
return current
- 上記例のように、
iteration
を止めるにはStopIteration
を使用します。
なぜiterator
を使うのか
ここでは、なぜ、どのようなケースであればList
などのiterable
なobjectではなく, iterator
を自分で定義するのか、を考えていきたいと思います。(考察のため、違う、他にもある、などのフィードバックは宝物として受け取ります。コメントいただけると幸いです。)
- 対象objectが単純なvalueではない
上記の例のように対象objectが単純なint
などではなく、class
だが、iterable
に操作したい場合、明示的に定義するのかと思います。 - 対象となるobjectのサイズが呼び出されるタイミングでは決定していない
上記例ですと、Point
はtuple(int, int) のため、List
やtuple
を組み合わせて表現することも可能に見えますが、実はこのコードでは他の制約によって(ここでは盤面のサイズ)List
の長さが変わります。List
を使って表現する場合は制約によって決定したサイズのList
を渡す必要がありますが、上記コードではiterator
の終了条件を自分で決定できるため、より柔軟なコードを書くことが可能になります。 - 見やすさ
List
やtuple
といったデータコンテナは、それ自体どのようなデータを含んでいるのか、なんのためのデータなのかが中身を見ないとわからないですが、class
では何を扱っているのか、が一目でわかるという明確なメリットがあります。