Skip to content

Генераторные функции в Python

Генераторная функция в Python — это особый тип функции, которая возвращает генератор-итератор. В отличие от обычных функций, которые возвращают одно значение с помощью оператора return, генераторные функции могут приостанавливать свое выполнение с помощью ключевого слова yield, сохраняя свое состояние для последующих вызовов.

Характеристики генераторов:

  • Ленивое вычисление: Значения генерируются по требованию, а не сразу.
  • Сохранение состояния: Функция приостанавливает выполнение при каждом вызове yield и возобновляет с того же места при следующем вызове.
  • Итерабельность: Генераторы можно использовать в циклах for.

Создание функции генератора:

python
def simple_generator():
    yield 1
    yield 2
    yield 3

gen = simple_generator()
print(next(gen))    # 1
print(next(gen))    # 2
print(next(gen))    # 3
print(next(gen))    # StopIteration

В этом примере функция simple_generator возвращает значения 1, 2 и 3 по мере их запроса в цикле for.

Преимущества:

  • Экономия памяти: Значения генерируются по мере необходимости, что особенно полезно для больших последовательностей.
  • Улучшение производительности: Ленивая обработка данных уменьшает задержки при начальной загрузке.
  • Упрощение кода: Генераторы могут упростить код, который иначе потребовал бы сложных итераторов.

Примеры использования:

Пример 1: Бесконечный генератор

python
def infinite_sequence():
    num = 0
    while True:
        yield num
        num += 1

gen = infinite_sequence()
for _ in range(5):
    print(next(gen))

Пример 2: Чтение большого файла

python
def read_large_file(file_object):
    while True:
        data = file_object.readline()
        if not data:
            break
        yield data

with open('large_file.txt') as file:
    for line in read_large_file(file):
        print(line, end='')

Разделения вложенных циклов с помощью генератора

Вложенные циклы могут быть сложными для чтения и поддержки. Генераторы могут упростить такую логику, разделяя каждый цикл в отдельный генератор.

Пример: Разделение вложенных циклов

python
# Decision without generators:
print("\nDecision without generators: ")
for i in range(3):
    for j in range(3):
        print((i, j), end=' ')


# Decision with generators:
def generate_outer():
    for i in range(3):
        yield from generate_inner(i)

def generate_inner(i):
    for j in range(3):
        yield (i, j)
        
print("\nDecision without generators: ")
for pair in generate_outer():
    print(pair, end=' ')

В этом примере функция generate_outer использует генератор generate_inner, чтобы упростить логику вложенных циклов.

Упражнения

  1. Генератор для чтения файла по строкам с обратным порядком: Создайте генератор, который читает строки файла и возвращает их в обратном порядке.
  2. Генератор для вычисления простых чисел: Напишите генератор, который генерирует простые числа до заданного предела.
  3. Генератор для комбинирования двух списков: Создайте генератор, который комбинирует элементы двух списков в пары.
  4. Выравнивание текста по заданной ширине по левому краю. Решить двумя способами без генератора и с генератором.
  5. Выравнивание текста по заданной ширине по двум сторонам. Решить двумя способами без генератора и с генератором.
  6. Создание шахматной доски с помощью итератора. Размер квадрата доски задается из исходной коллекции букв.

Contacts: teffal@mail.ru