← Назад к вопросам
В чем разница между функцией и генератором?
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, экономя память и повышая производительность при работе с большими данными.