Глянь мій новий курс по Git! Привіт! Глянь мій новий курс по Git! Привіт! Глянь мій новий курс по Git на GitByBit.com! Привіт! Хочеш класно освіжити Git? Глянь мій новий курс на GitByBit.com!
Ітератор

Ітератор на Python

Ітератор — це поведінковий патерн, що дозволяє послідовно обходити складну колекцію, не розкриваючи деталі її реалізації.

Завдяки Ітераторові, клієнт може обходити різні колекції в один і той же спосіб, використовуючи єдиний інтерфейс ітераторів.

Складність:

Популярність:

Застосування: Патерн можна часто зустріти в Python-коді, особливо в програмах, що працюють з різними типами колекцій, коли потрібно виконати обхід різних сутностей.

Ознаки застосування патерна: Ітератор легко визначити за методами навігації (наприклад, отримання наступного/попереднього елементу і т. д.). Код, який використовує ітератор, часто взагалі не має посилань на колекцію, з якою працює ітератор. Ітератор або приймає колекцію в параметрах конструктора під час створення, або повертається до самої колекцією.

Концептуальний приклад

Цей приклад показує структуру патерна Ітератор, а саме — з яких класів він складається, які ролі ці класи виконують і як вони взаємодіють один з одним.

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

Ітератор іншими мовами програмування

Ітератор на C# Ітератор на C++ Ітератор на Go Ітератор на Java Ітератор на PHP Ітератор на Ruby Ітератор на Rust Ітератор на Swift Ітератор на TypeScript