JustCaptain kod-buduschego
llm/senior-883e8c
Перейти к файлу
Код
kod-buduschego Python 2025-20264.3. Итераторы и генераторыMATERIAL.md
anc update c70a58f 8 октября 2026 г.
MATERIAL.md

Методический материал: Генераторы и итераторы в Python

Для кого этот материал

Материал рассчитан на новичков. Предполагается, что вы уже знаете:

  • переменные
  • циклы for
  • функции
  • списки (list)

Цель: понять, как Python перебирает данные, что такое итераторы, зачем нужны генераторы, и когда использовать каждый инструмент.

⸻

Глава 1. Что такое итерация

Начнём с простой мысли.

Когда вы пишете:

numbers = [10, 20, 30]
for number in numbers:
print(number)

Python перебирает элементы списка по одному:

  1. Берёт 10
  2. Берёт 20
  3. Берёт 30
  4. Останавливается

Этот процесс называется итерацией.

Итерация — это последовательный обход элементов объекта.

⸻

Что можно перебирать в Python

Объекты, которые можно перебирать циклом for, называются iterable (итерируемые объекты).

Примеры:

numbers = [1, 2, 3] # список
text = "hello" # строка
data = (10, 20, 30) # кортеж
my_set = {1, 2, 3} # множество
my_dict = {"a": 1} # словарь

Все они работают в for.

Пример:

for char in "Python":
print(char)

Результат:

P
y
t
h
o
n

⸻

Что реально делает цикл for

Многие думают, что for — магия.

На самом деле Python делает примерно следующее:

iterator = iter(numbers)
while True:
try:
value = next(iterator)
print(value)
except StopIteration:
break

Сейчас это может выглядеть страшно.

Разберём по частям.

⸻

Глава 2. Iterable и Iterator

Новички часто путают эти понятия.

Это ошибка.

Нужно чётко разделять:

Iterable

Объект, который можно начать перебирать.

Например:

numbers = [1, 2, 3]

Список — iterable.

Но сам список не хранит текущее положение перебора.

⸻

Iterator

Объект, который умеет выдавать следующий элемент.

У него есть состояние.

Он знает:

«Я уже отдал первые 2 элемента. Следующий — третий».

⸻

Получаем iterator из iterable

Для этого используется:

iter()

Пример:

numbers = [10, 20, 30]
iterator = iter(numbers)
print(iterator)

Результат:

<list_iterator object at ...>

Теперь у нас есть настоящий итератор.

⸻

next()

Чтобы получить следующий элемент, используется:

next()

Пример:

numbers = [10, 20, 30]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))

Результат:

10
20
30

⸻

Что будет дальше?

Попробуем ещё раз:

print(next(iterator))

Ошибка:

StopIteration

Почему?

Потому что элементы закончились.

⸻

Важная идея

Итератор нельзя «отмотать назад».

Он одноразовый.

Пример:

numbers = [1, 2, 3]
iterator = iter(numbers)
for item in iterator:
print(item)
for item in iterator:
print(item)

Результат:

1
2
3

Второй цикл ничего не выведет.

Потому что итератор уже исчерпан.

⸻

Аналогия из жизни

Представьте рулон билетов.

Итерируемый объект (iterable) — это весь рулон.

Итератор (iterator) — человек, который отрывает билет за билетом.

Он помнит:

«Уже выдал 5 билетов».

Назад приклеить нельзя.

⸻

Глава 3. Создание собственного итератора

Теперь создадим свой итератор.

Допустим, хотим объект, который выдаёт числа от 1 до 5.

⸻

Метод iter

Python вызывает его, чтобы начать перебор.

⸻

Метод next

Python вызывает его, чтобы получить следующий элемент.

⸻

Пример:

class Counter:
def init(self, max_value):
self.current = 1
self.max_value = max_value
def iter(self):
return self
def next(self):
if self.current > self.max_value:
raise StopIteration
value = self.current
self.current += 1
return value
counter = Counter(5)
for number in counter:
print(number)

Результат:

1
2
3
4
5

⸻

Разбор по шагам

Шаг 1

Создаётся объект:

counter = Counter(5)

Состояние:

current = 1
max_value = 5

⸻

Шаг 2

Цикл вызывает:

iter(counter)

Срабатывает:

iter()

Возвращается:

self

⸻

Шаг 3

Цикл вызывает:

next(counter)

Срабатывает:

next()

Возвращается:

1

Затем:

current += 1

Теперь:

current = 2

И так далее.

⸻

Когда всё заканчивается

Python получает:

raise StopIteration

И завершает цикл.

⸻

Проблема итераторов

Посмотрите на этот код:

counter = Counter(1_000_000)

Если сделать всё через список:

numbers = list(range(1_000_000))

Python сразу создаст миллион чисел в памяти.

Это дорого.

Решение — генераторы.

⸻

Глава 4. Генераторы

Генератор — это упрощённый способ создания итераторов.

Вместо:

iter()
next()
StopIteration

Python делает всё за нас.

Главное слово:

yield

⸻

Первый генератор

def my_generator():
yield 1
yield 2
yield 3
gen = my_generator()
print(next(gen))
print(next(gen))
print(next(gen))

Результат:

1
2
3

⸻

Что делает yield

yield временно останавливает функцию, сохраняя её состояние.

Это ключевая идея.

Обычная функция:

def test():
return 10

После return функция закончилась.

⸻

С yield иначе:

def test():
yield 10
yield 20

Функция «замораживается».

Потом продолжает работу с того места, где остановилась.

⸻

Как это работает

Пример:

def generator():
print("start")
yield 1
print("middle")
yield 2
print("end")
yield 3

Запуск:

gen = generator()
print(next(gen))
print(next(gen))
print(next(gen))

Результат:

start
1
middle
2
end
3

Функция не выполняется целиком сразу.

Она запускается частями.

⸻

Почему генераторы полезны

Главное преимущество:

Экономия памяти

Плохо:

numbers = [x for x in range(1_000_000)]

Хорошо:

numbers = (x for x in range(1_000_000))

Во втором случае числа создаются по мере необходимости.

Это называется:

lazy evaluation — ленивые вычисления.

В следующей части: generator expressions, yield from, реальные примеры (чтение больших файлов, API, бесконечные последовательности), частые ошибки новичков и практические задачи.