Добавить в корзинуПозвонить
Найти в Дзене

…Итерируемый объект, для которого запрашивается итерация…

*** …Вы сможете понять и объяснить такую фразу: "…итерируемый объект, для которого запрашивается итерация, чей метод __iter__ запускается методом iter; объект итератора, возвращённый итерируемым объектом, который фактически производит значения во время итерации…"?.. Это описание относится к механизму работы циклов for/while и встроенной функции iter() в языке Python (цитата из книги: Марк Лутц. Изучаем Python. М., СПб, 2020. Т. 1. С. 443. [оригинальное название – Mark Lutz. Learning Python; перевод с английского Ю.Н. Артеменко]). Давайте разберём эту фразу по частям: Это любой объект Python, способный возвращать свои элементы по одному за раз. Примеры: списки (list), кортежи (tuple), строки (str), словари (dict) или файлы. Главное требование к такому объекту – наличие специального метода __iter__. Запрос итерации происходит, когда вы используете цикл for, передаёте объект в функцию iter() или распаковываете его с помощью оператора *. В этот момент Python понимает, что ему нужно пройти
Оглавление

***

…Вы сможете понять и объяснить такую фразу: "…итерируемый объект, для которого запрашивается итерация, чей метод __iter__ запускается методом iter; объект итератора, возвращённый итерируемым объектом, который фактически производит значения во время итерации…"?..

Это описание относится к механизму работы циклов for/while и встроенной функции iter() в языке Python (цитата из книги: Марк Лутц. Изучаем Python. М., СПб, 2020. Т. 1. С. 443. [оригинальное название – Mark Lutz. Learning Python; перевод с английского Ю.Н. Артеменко]).

Давайте разберём эту фразу по частям:

1. "итерируемый объект" (Iterable Object)

Это любой объект Python, способный возвращать свои элементы по одному за раз. Примеры: списки (list), кортежи (tuple), строки (str), словари (dict) или файлы.

Главное требование к такому объекту – наличие специального метода __iter__.

2. "для которого запрашивается итерация"

Запрос итерации происходит, когда вы используете цикл for, передаёте объект в функцию iter() или распаковываете его с помощью оператора *. В этот момент Python понимает, что ему нужно пройти по всем элементам объекта.

3. "чей метод iter запускается…"

Когда поступает запрос на итерацию, интерпретатор Python внутренне вызывает метод __iter__() этого объекта. Именно этот метод отвечает за подготовку объекта к обходу.

4. "…методом iter"

Эта часть определения может показаться избыточной, но она подчёркивает суть протокола итерации. Метод __iter__ вызывается самим механизмом языка (внутренним методом iter()). Важно понимать разницу между итерированием самого объекта и получением итератора из него.

5. "объект итератора"

Это специальный объект в Python, созданный для обхода коллекции. Он не хранит всю коллекцию целиком (хотя может ссылаться на неё), а лишь отслеживает текущее состояние обхода: какой элемент был возвращён последним и какой будет следующим.

6. "возвращённый итерируемым объектом"

Итератор не существует сам по себе для данной коллекции. Его создаёт сам итерируемый объект при вызове функции iter(). Например, когда вы пишете for x in my_list, Python сначала вызывает iter(my_list). Метод списка __iter__ создаёт и возвращает новый объект-итератор, "привязанный" к этому списку.

7. "который фактически производит значения во время итерации"

Это главная функция итератора. Именно он отвечает за выдачу следующего элемента. Когда цикл for переходит к следующей итерации, он вызывает метод __next__() у объекта-итератора. Тот вычисляет следующий элемент и возвращает его. Этот процесс продолжается до тех пор, пока элементы не закончатся.

***

Как это работает на практике

# Ручная итерация, 1-й вариант (с использованием встроенной функции next()):

my_list = [10, 20, 30] # Создаём итерируемый объект (список чисел)

list_iterator = iter(my_list) # Создаём итератор из нашего объекта

print(next(list_iterator)) # -> 10 (ИТЕРАЦИЯ: мы получили 1-й элемент)

print(next(list_iterator)) # -> 20 (ИТЕРАЦИЯ: мы получили 2-й элемент)

print(next(list_iterator)) # -> 30 (ИТЕРАЦИЯ: мы получили последний элемент)

***

# Ручная итерация, 2-й вариант (с использованием метода __next__()):

my_list = [10, 20, 30] # Создаём итерируемый объект (список чисел)

list_iterator = iter(my_list) # Создаём итератор из нашего объекта

print(list_iterator.__next__()) # -> 10 (ИТЕРАЦИЯ: мы получили 1-й элемент)

print(list_iterator.__next__()) # -> 20 (ИТЕРАЦИЯ: мы получили 2-й элемент)

print(list_iterator.__next__()) # -> 30 (ИТЕРАЦИЯ: мы получили последний элемент)

-2

***

# Итерация с использованием встроенной функции next() и цикла while:

my_list = [10, 20, 30] # Создаём итерируемый объект (список чисел)

list_iterator = iter(my_list) # Создаём итератор из нашего объекта

while True:

try: # Перехватываем исключение StopIteration с помощью оператора try

X = next(list_iterator)

except StopIteration:

break

print(X, end=' ') # 10 20 30

-3

***

# Итерация с использованием метода __next__() и цикла while:

my_list = [10, 20, 30] # Создаём итерируемый объект (список чисел)

list_iterator = iter(my_list) # Создаём итератор из нашего объекта

while True:

try: # Перехватываем исключение StopIteration с помощью оператора try

X = list_iterator.__next__()

except StopIteration:

break

print(X, end=' ') # 10 20 30

-4

***

# Автоматическая итерация (с использованием цикла for):

my_list = [10, 20, 30] # Создаём итерируемый объект (список чисел)

for item in my_list: # автоматическая итерация

print(item, end=' ') # 10 20 30

-5

***

Ключевое различие между Iterable и Iterator

• Итерируемый объект" (Iterable Object) – это то, что можно обойти. У него есть метод __iter__, но нет метода __next__ (например, список [10, 20, 30]).

• Итератор (Iterator) – это то, что обходит. У него есть метод __next__. Он является "одноразовым": после того, как вы дошли до конца, вернуться в начало без создания нового итератора нельзя.

***

Немного этимологии (вместо послевкусия послесловия)

В переводе с великого и могучего латинского:

• iteratio – повторение.

В переводе с великого и могучего английского:

• iterate – повторять

• iterable – повторяемый

***

Примечание

Встроенный текстовый dzen-редактор не позволяет сохранять отступы в публикуемом программном коде (отсутствие этих отступов в Python приведёт к ошибке!).