Функции-генераторы
Лениво создавайте значения с помощью yield
«Функции-генераторы» — бесплатный урок Python Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.
Что такое генератор
Функция-генератор выглядит как обычная функция, но использует yield вместо return или вместе с ним. Её вызов не выполняет тело функции, а возвращает объект-генератор, который является итератором.
def gen():
yield 1
yield 2
yield 3
g = gen()
print(type(g).__name__)
print(list(g))yield приостанавливает выполнение
При каждом вызове next() функция выполняется до первого yield, возвращает это значение и сохраняет своё состояние. Следующий вызов продолжает выполнение сразу после yield.
def steps():
print('start')
yield 'a'
print('resumed')
yield 'b'
g = steps()
print(next(g))
print(next(g))Перебор генератора в цикле
Поскольку генератор является итератором, цикл for автоматически управляет им и останавливается, когда функция завершается, то есть внутри возникает StopIteration.
def countdown(n):
while n > 0:
yield n
n -= 1
for x in countdown(4):
print(x)Ленивое вычисление
Генераторы работают лениво: значения создаются только по запросу. Поэтому с их помощью можно моделировать очень большие или бесконечные последовательности, не расходуя много памяти.
def naturals():
n = 1
while True:
yield n
n += 1
g = naturals()
print(next(g), next(g), next(g))Состояние между yield
Локальные переменные сохраняют свои значения между точками yield. Генератор сам запоминает место, на котором остановился, поэтому вручную вести индекс не нужно.
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
g = fib()
print([next(g) for _ in range(7)])Генераторы и построение списка
Обычная функция создаёт и возвращает весь список сразу. Генератор выдаёт элементы по мере необходимости. Используйте генератор, когда последовательность велика или выполнение может завершиться досрочно.
def squares_list(n):
result = []
for i in range(n):
result.append(i * i)
return result
def squares_gen(n):
for i in range(n):
yield i * i
print(squares_list(5))
print(list(squares_gen(5)))Досрочная остановка
Поскольку значения создаются лениво, можно выйти из цикла, и генератор просто не будет вычислять оставшуюся часть.
def naturals():
n = 1
while True:
print('producing', n)
yield n
n += 1
for x in naturals():
if x > 3:
break
print('got', x)return внутри генератора
Обычный return в генераторе просто завершает его, вызывая StopIteration. Любое возвращённое Вами значение становится атрибутом value исключения, который большинство циклов игнорирует.
def up_to(stop):
i = 0
while True:
if i >= stop:
return
yield i
i += 1
print(list(up_to(4)))Генераторы можно использовать только один раз
Как и любой итератор, генератор используется один раз. После исчерпания он больше ничего не выдаёт. Чтобы получить новый генератор, снова вызовите функцию.
def gen():
yield 1
yield 2
g = gen()
print(list(g))
print(list(g))
print(list(gen()))Фильтрация с помощью генераторов
Генераторы позволяют создавать понятные конвейеры обработки данных. Здесь мы выдаём только чётные числа, по одному за раз.
def evens(numbers):
for n in numbers:
if n % 2 == 0:
yield n
print(list(evens(range(10))))Объединение генераторов
Один генератор может потреблять другой, образуя многоэтапный конвейер, в котором каждый этап работает лениво.
def numbers(n):
for i in range(n):
yield i
def doubled(src):
for x in src:
yield x * 2
print(list(doubled(numbers(5))))Быстрая проверка
Проверьте, насколько хорошо Вы понимаете функции-генераторы.
Итоги
Вы изучили функции-генераторы:
yieldприостанавливает и возобновляет выполнение, сохраняя локальное состояние.- Вызов функции возвращает ленивый объект-генератор.
- Генераторы экономят память и отлично подходят для конвейеров и бесконечных потоков.
- Их можно использовать только один раз, как и любой итератор.
Далее Вы изучите ещё более компактные выражения-генераторы.
Часто задаваемые вопросы
Урок «Функции-генераторы» бесплатный?
Да — полный текст урока «Функции-генераторы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.
Чему я научусь в уроке «Функции-генераторы»?
Лениво создавайте значения с помощью yield Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Python Academy?
Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Функции-генераторы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Python Academy?
Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Протокол итератора
- Функции-генераторы
- Выражения-генераторы
- yield from и делегирование