10 итераторов, о которых вы могли не знать
Одним из главных достоинств Python является выразительность кода. Не последнюю роль в этом играет возможность удобной работы с коллекциями и последовательностями различного вида: перебор элементов списка по одному, чтение файла по строкам, обработка всех ключей и значений в словаре. Эти и многие другие подобные задачи в Python помогает решить так называемый протокол итераторов (Iterator protocol). Именно этот протокол обеспечивает работу цикла for
, устанавливает по каким объектам можно итерироваться, а по каким нет. Как мы увидим далее, сам язык и стандартная библиотека очень широко используют возможности протокола. В этой статье попробуем отыскать не самые известные, но от этого не менее интересные примеры итераторов и итерируемых объектов, которые предлагает Python.
0. В качестве вступления
Для начала предлагаю освежить в памяти, что же из себя представляет упомянутый протокол итераторов. В сущности, протокол определяет два вида объектов. Первый вид — это объекты, которые можно использовать в цикле for
, поэтому они и называются итерируемыми (Iterable). К первому виду принадлежат списки, строки, словари, множества, а также многие другие коллекции. Итерируемые объекты вовсе не обязательно должны иметь конечное число элементов, например, последовательность натуральных чисел легко можно использовать в цикле for
(хотя завершения подобной программы придётся ждать довольно долго):
from itertools import count
# Последовательность натуральных чисел
natural_numbers = count(start=1, step=1)
for number in natural_numbers:
print(number) # Напечатает 1, 2, 3, и т.д.
Все итерируемые объекты объединяет одно важное свойство. Если передать такой объект в функцию iter
, то она отработает без ошибок и вернёт объект второго вида, который нам интересен в рамках этой статьи.
Как не сложно догадаться по самому названию протокола, этим вторым видом объектов являются итераторы. Каждый итератор неразрывно связан со своим итерируемым объектом. Единственное, что «знает» итератор — это какой элемент в итерируемом объекте будет следующим при переборе. Этот элемент он и возвращает при вызове функции next
:
# Итерируемый объект
iterable = ["