Appearance
Генераторные функции в 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
, чтобы упростить логику вложенных циклов.
Упражнения
- Генератор для чтения файла по строкам с обратным порядком: Создайте генератор, который читает строки файла и возвращает их в обратном порядке.
- Генератор для вычисления простых чисел: Напишите генератор, который генерирует простые числа до заданного предела.
- Генератор для комбинирования двух списков: Создайте генератор, который комбинирует элементы двух списков в пары.
- Выравнивание текста по заданной ширине по левому краю. Решить двумя способами без генератора и с генератором.
- Выравнивание текста по заданной ширине по двум сторонам. Решить двумя способами без генератора и с генератором.
- Создание шахматной доски с помощью итератора. Размер квадрата доски задается из исходной коллекции букв.