
Iterator を Python で
Iterator は、 振る舞いに関するデザインパターンの一つで、 複雑なデータ構造の内部の詳細を公開することなく、 順次横断的に探索することを可能とします。
Iterator のおかげで、 クライアントは、 異なるコレクション上の要素の探索を、 単一のイテレーター・インターフェースを使用して同様の方法で行えます。
複雑度:
人気度:
使用例: このパターンは、 Python コードではよく見かけます。 多くのフレームワークやライブラリーがこれを使用してコレクション上の探索の標準的方法を提供します。
見つけ方: Iterator は、 next
や previous
などの操舵用メソッドの存在から簡単に識別できます。 イテレーターを使ったクライアント・コードには、 探索対象のコレクションへの直接のアクセスがないかもしれません。
概念的な例
この例は、 Iterator デザインパターンの構造を説明するためのものです。 以下の質問に答えることを目的としています:
- どういうクラスからできているか?
- それぞれのクラスの役割は?
- パターンの要素同士はどう関係しているのか?
main.py: 概念的な例
from __future__ import annotations from collections.abc import Iterable, Iterator from typing import Any """ To create an iterator in Python, there are two abstract classes from the built- in `collections` module - Iterable,Iterator. We need to implement the `__iter__()` method in the iterated object (collection), and the `__next__ ()` method in theiterator. """ class AlphabeticalOrderIterator(Iterator): """ Concrete Iterators implement various traversal algorithms. These classes store the current traversal position at all times. """ """ `_position` attribute stores the current traversal position. An iterator may have a lot of other fields for storing iteration state, especially when it is supposed to work with a particular kind of collection. """ _position: int = None """ This attribute indicates the traversal direction. """ _reverse: bool = False def __init__(self, collection: WordsCollection, reverse: bool = False) -> None: self._collection = collection self._reverse = reverse self._sorted_items = None # Will be set on first __next__ call self._position = 0 def __next__(self) -> Any: """ Optimization: sorting happens only when the first items is actually requested. """ if self._sorted_items is None: self._sorted_items = sorted(self._collection._collection) if self._reverse: self._sorted_items = list(reversed(self._sorted_items)) """ The __next__() method must return the next item in the sequence. On reaching the end, and in subsequent calls, it must raise StopIteration. """ if self._position >= len(self._sorted_items): raise StopIteration() value = self._sorted_items[self._position] self._position += 1 return value class WordsCollection(Iterable): """ Concrete Collections provide one or several methods for retrieving fresh iterator instances, compatible with the collection class. """ def __init__(self, collection: list[Any] | None = None) -> None: self._collection = collection or [] def __getitem__(self, index: int) -> Any: return self._collection[index] def __iter__(self) -> AlphabeticalOrderIterator: """ The __iter__() method returns the iterator object itself, by default we return the iterator in ascending order. """ return AlphabeticalOrderIterator(self) def get_reverse_iterator(self) -> AlphabeticalOrderIterator: return AlphabeticalOrderIterator(self, True) def add_item(self, item: Any) -> None: self._collection.append(item) if __name__ == "__main__": # The client code may or may not know about the Concrete Iterator or # Collection classes, depending on the level of indirection you want to keep # in your program. collection = WordsCollection() collection.add_item("B") collection.add_item("A") collection.add_item("C") print("Straight traversal:") print("\n".join(collection)) print("") print("Reverse traversal:") print("\n".join(collection.get_reverse_iterator()), end="")
Output.txt: 実行結果
Straight traversal: A B C Reverse traversal: C B A