Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как происходит итерация в Python
Итерация — это процесс последовательного обхода элементов контейнера. Понимание механики итерации критично для написания эффективного Python кода и создания собственных итерируемых объектов.
Теория: Iterables, Iterators и Protocol
В Python есть три ключевых концепции:
1. Iterable (Итерируемый объект)
Любой объект, который имеет метод __iter__(), возвращающий итератор:
my_list = [1, 2, 3]
print(hasattr(my_list, '__iter__')) # True
# Вызов __iter__() создаёт итератор
iterator = iter(my_list)
print(type(iterator)) # <class 'list_iterator'>
2. Iterator (Итератор)
Объект с двумя методами: __iter__() (возвращает сам себя) и __next__() (возвращает следующий элемент):
my_iter = iter([1, 2, 3])
print(next(my_iter)) # 1
print(next(my_iter)) # 2
print(next(my_iter)) # 3
print(next(my_iter)) # StopIteration ← исключение
Практический пример: что происходит в цикле
# Когда ты пишешь:
for item in [1, 2, 3]:
print(item)
# Python делает РОВНО ЭТО:
my_iter = iter([1, 2, 3]) # Вызов __iter__()
while True:
try:
item = next(my_iter) # Вызов __next__()
print(item)
except StopIteration:
break # Выход из цикла
Создание собственного итератора
Способ 1: Класс с iter() и next()
class CountUp:
def __init__(self, max):
self.max = max
self.current = 0
def __iter__(self):
return self # Возвращаем сам объект как итератор
def __next__(self):
if self.current < self.max:
self.current += 1
return self.current
else:
raise StopIteration # Сигнал конца итерации
# Использование
for num in CountUp(3):
print(num) # 1, 2, 3
Способ 2: Генератор (самый Pythonic способ)
Генератор автоматически реализует протокол итератора:
def count_up(max):
current = 0
while current < max:
current += 1
yield current # Приостанавливает и возвращает значение
# Использование
for num in count_up(3):
print(num) # 1, 2, 3
# Генератор «ленивый» — создаёт значения по требованию
gen = count_up(3)
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
Разница между Iterables и Iterators
# Iterable — можешь вызвать iter() и получить итератор
my_list = [1, 2, 3]
iterator1 = iter(my_list) # Каждый раз новый итератор
iterator2 = iter(my_list)
print(iterator1 is iterator2) # False — разные объекты
# Iterator — одновременно итератор и итерируемый
my_iter = iter([1, 2, 3])
print(my_iter is iter(my_iter)) # True — всегда возвращает себя
# Важно: дважды итерировать список можно, но не итератор
data = [1, 2, 3]
for x in data:
print(x) # 1, 2, 3
for x in data:
print(x) # 1, 2, 3 — работает заново
my_iter = iter(data)
for x in my_iter:
print(x) # 1, 2, 3
for x in my_iter:
pass # Не печатает ничего — итератор уже исчерпан
Встроенные функции для итерации
enumerate() — получить индекс и значение:
for index, item in enumerate(['a', 'b', 'c'], start=1):
print(f"{index}: {item}") # 1: a, 2: b, 3: c
zip() — объединить несколько итерируемых:
names = ['Alice', 'Bob']
ages = [25, 30]
for name, age in zip(names, ages):
print(f"{name}: {age}") # Alice: 25, Bob: 30
map() и filter() — функциональное программирование:
numbers = [1, 2, 3, 4, 5]
# map — преобразование каждого элемента
squared = map(lambda x: x ** 2, numbers)
print(list(squared)) # [1, 4, 9, 16, 25]
# filter — выбор элементов по условию
evens = filter(lambda x: x % 2 == 0, numbers)
print(list(evens)) # [2, 4]
Важные особенности
Генераторы — ленивые вычисления:
import sys
# Список хранит ВСЕ значения в памяти
big_list = [x for x in range(1_000_000)]
print(sys.getsizeof(big_list)) # ~8 млн байт
# Генератор создаёт значения по требованию
big_gen = (x for x in range(1_000_000))
print(sys.getsizeof(big_gen)) # ~128 байт
# Для итерации одинаково работает
for num in big_gen:
if num > 5:
break
StopIteration в Python 3.7+:
def my_gen():
yield 1
yield 2
return 3 # Значение возвращается в StopIteration.value
gen = my_gen()
print(next(gen)) # 1
print(next(gen)) # 2
try:
next(gen) # Вызывает StopIteration
except StopIteration as e:
print(e.value) # 3
Вывод
Итерация в Python — это протокол, основанный на методах __iter__() и __next__(). Это позволяет создавать мощные, ленивые и эффективные по памяти конструкции. Генераторы — идеальный способ реализации итераторов в большинстве случаев.