← Назад к вопросам

Простой генератор

2.0 Middle🔥 121 комментариев
#Другое

Условие

Напишите генератор, который yield-ит квадраты чисел от 1 до n.

Пример

for sq in squares(5): print(sq)

Вывод:

1

4

9

16

25

Дополнительно

Объясните разницу между генератором и итератором.

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение: Простой Генератор и Итераторы

Генератор — это функция, которая возвращает значения по одному, экономя память. Это мощный инструмент Python для работы с последовательностями.

Подход 1: Простой Генератор

Используем yield для возврата значений:

def squares(n: int):
    for i in range(1, n + 1):
        yield i * i

for sq in squares(5):
    print(sq)

Вывод:

1
4
9
16
25

Подход 2: Генератор с Выражением

Компактная форма с generator expression:

def squares(n: int):
    return (i * i for i in range(1, n + 1))

for sq in squares(5):
    print(sq)

Это не совсем функция-генератор, а генераторное выражение, но работает одинаково.

Подход 3: Генератор с Дополнительной Логикой

Можно добавить фильтрацию или трансформацию:

def squares(n: int, start: int = 1, step: int = 1):
    for i in range(start, n + 1, step):
        yield i * i

for sq in squares(10, start=2, step=2):
    print(sq)

Вывод:

4
16
36
64
100

Разница между Генератором и Итератором

Итератор — объект с методами __iter__() и __next__():

class SquaresIterator:
    def __init__(self, n: int):
        self.n = n
        self.current = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.current < self.n:
            self.current += 1
            return self.current ** 2
        else:
            raise StopIteration

for sq in SquaresIterator(5):
    print(sq)

Генератор — частный случай итератора, создаётся с помощью функции с yield:

def squares(n: int):
    for i in range(1, n + 1):
        yield i * i

for sq in squares(5):
    print(sq)

Ключевые Отличия

АспектИтераторГенератор
ОпределениеКласс с __iter__ и __next__Функция с yield
КодБольше кода, явная логикаМеньше кода, компактнее
ПамятьЗависит от реализацииЛенивое вычисление, минимум памяти
СостояниеЯвно сохраняется в атрибутахСохраняется неявно в стеке вызовов
ПростотаСложнее для начинающихИнтуитивнее и читабельнее
ПроизводительностьНемного быстрееНемного медленнее, но разница минимальна

Практические Примеры

# Генератор чисел Фибоначчи
def fibonacci(limit: int):
    a, b = 0, 1
    while a < limit:
        yield a
        a, b = b, a + b

for num in fibonacci(100):
    print(num, end=' ')

# Генератор строк из файла
def read_lines(filename: str):
    with open(filename) as f:
        for line in f:
            yield line.strip()

for line in read_lines('data.txt'):
    print(line)

# Чтение большого файла без загрузки в память
def chunked_read(filename: str, chunk_size: int = 1024):
    with open(filename, 'rb') as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            yield chunk

Преимущества Генераторов

1. Экономия памяти:

# Плохо: загружает всё в память
squares_list = [i * i for i in range(1000000)]

# Хорошо: ленивое вычисление
squares_gen = (i * i for i in range(1000000))

2. Бесконечные последовательности:

def infinite_counter():
    n = 0
    while True:
        yield n
        n += 1

for num in infinite_counter():
    if num > 5:
        break
    print(num)

3. Конвейеры обработки данных:

def numbers():
    for i in range(5):
        yield i

def squared(numbers):
    for n in numbers:
        yield n * n

def filtered(numbers):
    for n in numbers:
        if n > 5:
            yield n

result = filtered(squared(numbers()))
for num in result:
    print(num)

Рекомендация

Используй генератор для этой задачи — это стандартный питонический способ:

  • Компактный и читаемый код
  • Минимум памяти
  • Естественная семантика для последовательностей
  • Показывает понимание концепций Python

Если попросят отличия от итератора, объясни: генератор — это удобный способ создать итератор без написания класса с методами __iter__ и __next__.

Простой генератор | PrepBro