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

В чем разница между функцией и генератором?

1.0 Junior🔥 161 комментариев
#Python Core

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

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

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

Разница между функцией и генератором

Генератор — это специальный тип функции, которая использует yield вместо return и возвращает итератор вместо полного результата.

Основные различия

Функция:

def get_numbers():
    result = []
    for i in range(5):
        result.append(i)
    return result  # Возвращает всё за раз

numbers = get_numbers()
print(numbers)  # [0, 1, 2, 3, 4]

Генератор:

def get_numbers():
    for i in range(5):
        yield i  # Возвращает по одному значению

gen = get_numbers()  # Не выполняется сразу!
print(next(gen))     # 0
print(next(gen))     # 1
print(next(gen))     # 2

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

def simple_generator():
    print("Начало")
    yield 1
    print("Середина 1")
    yield 2
    print("Середина 2")
    yield 3
    print("Конец")

gen = simple_generator()  # Ничего не выполнилось!
print(type(gen))  # <class 'generator'>

print(next(gen))  # Печатает "Начало", возвращает 1
print(next(gen))  # Печатает "Середина 1", возвращает 2
print(next(gen))  # Печатает "Середина 2", возвращает 3
# next(gen)       # StopIteration

Сравнение памяти

# Функция: загружает всё в память
def numbers_function():
    result = []
    for i in range(1_000_000):
        result.append(i)
    return result

# Использует ~40MB памяти
nums = numbers_function()

# Генератор: ленивые вычисления
def numbers_generator():
    for i in range(1_000_000):
        yield i

# Использует ~200 байт
gen = numbers_generator()

Итерирование

# Функция
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    print(num)

# Генератор
def numbers_gen():
    for i in [1, 2, 3, 4, 5]:
        yield i

for num in numbers_gen():
    print(num)  # Результат одинаковый

Вычисления с функцией

# Функция: вычисляет и возвращает весь список
def get_squares():
    squares = []
    for i in range(10):
        squares.append(i ** 2)
    return squares

result = get_squares()  # Вычисляет все сразу
print(result[0])  # 0
print(result[1])  # 1

Вычисления с генератором

# Генератор: вычисляет по требованию
def get_squares():
    for i in range(10):
        yield i ** 2

gen = get_squares()  # Ничего не вычислено
print(next(gen))  # Вычисляет первый: 0
print(next(gen))  # Вычисляет второй: 1

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

Функция — чтение файла:

def read_file_function(filename):
    with open(filename) as f:
        lines = f.readlines()  # Загрузить всё
    return lines

lines = read_file_function('large_file.txt')  # Может не хватить памяти!

Генератор — чтение файла:

def read_file_generator(filename):
    with open(filename) as f:
        for line in f:
            yield line.strip()  # По одной строке

for line in read_file_generator('large_file.txt'):  # Безопасно!
    print(line)

Функция — Fibonacci:

def fib_function(n):
    result = []
    a, b = 0, 1
    for _ in range(n):
        result.append(a)
        a, b = b, a + b
    return result

print(fib_function(10))  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Генератор — Fibonacci:

def fib_generator(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

for num in fib_generator(10):
    print(num)  # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Выражения-генераторы (Generator Expressions)

# List comprehension
squares = [x ** 2 for x in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, ...]

# Generator expression
squares_gen = (x ** 2 for x in range(10))  # Скобки вместо квадратных!
print(next(squares_gen))  # 0
print(next(squares_gen))  # 1

# Или через итерацию
for square in (x ** 2 for x in range(10)):
    print(square)

Встроенные генераторы

# range — генератор
for i in range(1_000_000):
    print(i)  # Не загружает все в память

# zip, map, filter — генераторы
result = map(lambda x: x ** 2, range(10))
print(next(result))  # 0

result = filter(lambda x: x % 2 == 0, range(10))
print(next(result))  # 0

Отправка значений в генератор

def echo_generator():
    value = None
    while True:
        value = yield value

gen = echo_generator()
print(next(gen))           # None
print(gen.send(10))        # 10
print(gen.send(20))        # 20
print(gen.send(30))        # 30

Сравнение производительности

import time

# Функция
start = time.time()
nums = [i for i in range(10_000_000)]
print(f"List: {time.time() - start:.3f}s")  # ~0.5s, 400MB память

# Генератор
start = time.time()
gen = (i for i in range(10_000_000))
print(f"Generator: {time.time() - start:.3f}s")  # ~0.0001s, минимум памяти

Когда использовать

Функция:

  • Нужны все результаты сразу
  • Данные небольшого размера
  • Нужен индексный доступ

Генератор:

  • Большие последовательности
  • Дорогостоящие вычисления
  • Потоки данных (файлы, API)
  • Нужна лень вычисления

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

В чем разница между функцией и генератором? | PrepBro