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では何を扱っているのか、が一目でわかるという明確なメリットがあります。