Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Зачем нужен итератор
Итератор — это объект, который позволяет перебирать элементы последовательности по одному. Это фундаментальный концепт Python, без которого невозможно представить современную разработку.
Что такое итератор
Итератор — это объект, который реализует два метода:
__iter__()— возвращает сам итератор__next__()— возвращает следующий элемент и передвигает указатель
# Пример простого итератора
class CountIterator:
def __init__(self, max):
self.max = max
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.max:
self.current += 1
return self.current
else:
raise StopIteration
# Использование
counter = CountIterator(3)
for num in counter:
print(num) # 1, 2, 3
# Или явно через next()
counter = CountIterator(3)
print(next(counter)) # 1
print(next(counter)) # 2
print(next(counter)) # 3
# next(counter) # StopIteration exception
Основные преимущества итераторов
1. Экономия памяти
Итератор не хранит все элементы в памяти, а генерирует их по требованию.
# ❌ Плохо — весь список в памяти
data = [i for i in range(1_000_000)] # ~40 МБ
for item in data:
process(item)
# ✅ Хорошо — итератор генерирует по одному
data = (i for i in range(1_000_000)) # Минимум памяти
for item in data:
process(item)
2. Ленивое вычисление
Элементы вычисляются только когда они нужны, а не заранее.
# ❌ Все вычисляется сразу
result = [x ** 2 for x in range(10)]
print(result[0]) # Но мы используем только первый!
# ✅ Вычисляется только нужное
result = (x ** 2 for x in range(10))
print(next(result)) # Вычислено только одно значение
3. Работа с бесконечными последовательностями
# Бесконечный итератор
class InfiniteCounter:
def __init__(self, start=0):
self.current = start
def __iter__(self):
return self
def __next__(self):
self.current += 1
return self.current
# Использование
counter = InfiniteCounter()
for i, num in enumerate(counter):
if i >= 5:
break
print(num) # 1, 2, 3, 4, 5
# Со списком это невозможно
4. Цепочка трансформаций
# Сложная трансформация без итераторов
data = [1, 2, 3, 4, 5]
data = [x * 2 for x in data] # Создаёт список
data = [x for x in data if x > 4] # Создаёт список
data = [str(x) for x in data] # Создаёт список
# С итераторами — никаких промежуточных списков
data = [1, 2, 3, 4, 5]
result = map(lambda x: x * 2, data) # Итератор
result = filter(lambda x: x > 4, result) # Итератор
result = map(str, result) # Итератор
list(result) # ["6", "8", "10"] — только один список в конце
Встроенные итераторы в Python
map() — преобразование элементов
data = [1, 2, 3, 4, 5]
squared = map(lambda x: x ** 2, data)
print(next(squared)) # 1
print(next(squared)) # 4
print(next(squared)) # 9
# Или в цикле
for value in squared:
print(value)
filter() — фильтрация элементов
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = filter(lambda x: x % 2 == 0, data)
for value in evens:
print(value) # 2, 4, 6, 8, 10
zip() — объединение последовательностей
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name}: {age}") # Alice: 25, Bob: 30, ...
enumerate() — с индексом
for i, item in enumerate(['a', 'b', 'c']):
print(f"{i}: {item}") # 0: a, 1: b, 2: c
reversed() — в обратном порядке
for item in reversed([1, 2, 3, 4, 5]):
print(item) # 5, 4, 3, 2, 1
Модуль itertools — продвинутые итераторы
import itertools
# cycle() — бесконечный цикл
colors = itertools.cycle(['red', 'green', 'blue'])
for i, color in enumerate(colors):
if i >= 6:
break
print(color) # red, green, blue, red, green, blue
# chain() — объединение итераторов
data1 = [1, 2, 3]
data2 = [4, 5, 6]
for item in itertools.chain(data1, data2):
print(item) # 1, 2, 3, 4, 5, 6
# combinations() — все комбинации
for combo in itertools.combinations([1, 2, 3], 2):
print(combo) # (1,2), (1,3), (2,3)
# permutations() — все перестановки
for perm in itertools.permutations([1, 2, 3], 2):
print(perm) # (1,2), (1,3), (2,1), ...
# groupby() — группировка
data = [1, 1, 2, 2, 2, 3, 3]
for key, group in itertools.groupby(data):
print(f"{key}: {list(group)}") # 1: [1,1], 2: [2,2,2], 3: [3,3]
Практические примеры
1. Чтение больших файлов
# Без итератора — весь файл в памяти
with open('huge_file.txt') as f:
lines = f.readlines() # Может быть 1 ГБ
for line in lines:
process(line)
# С итератором — по одной строке
with open('huge_file.txt') as f:
for line in f: # f — это итератор
process(line)
2. Обработка данных из БД
from sqlalchemy import select
# ❌ Неправильно — вся БД в памяти
users = db.query(User).all()
for user in users:
process(user)
# ✅ Правильно — по одному пользователю
for user in db.query(User).yield_per(100): # Итератор по 100 записей
process(user)
3. Асинхронная обработка
async def fetch_data():
for page in range(1, 100):
data = await fetch_page(page)
yield data # Асинхронный итератор
async for batch in fetch_data():
process(batch)
4. Streaming HTTP ответов
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
def generate():
for i in range(1000):
yield f"data: {i}\n"
@app.get("/stream")
async def stream():
return StreamingResponse(generate(), media_type="text/event-stream")
Пользовательский итератор
class FileReader:
"""Итератор для чтения файла по частям"""
def __init__(self, filename, chunk_size=1024):
self.filename = filename
self.chunk_size = chunk_size
self.file = None
def __iter__(self):
self.file = open(self.filename, 'rb')
return self
def __next__(self):
chunk = self.file.read(self.chunk_size)
if chunk:
return chunk
else:
self.file.close()
raise StopIteration
# Использование
for chunk in FileReader('large_file.bin', chunk_size=8192):
process(chunk) # Обрабатываем по 8 КБ
Отличие от списков
# Список — все в памяти, индексирование
data = [1, 2, 3, 4, 5]
print(data[2]) # Работает
for item in data:
print(item)
# Итератор — по одному, нет индексирования
data = (x for x in range(1, 6))
# print(data[2]) # TypeError — нельзя!
for item in data: # Только так
print(item)
# После прохода итератор исчерпан
data = iter([1, 2, 3])
list(data) # [1, 2, 3]
list(data) # [] — пусто!
Когда использовать итераторы
# ✅ Используйте итераторы для:
# - Больших наборов данных
# - Потоковой обработки
# - Бесконечных последовательностей
# - Оптимизации памяти
# - Pipeline обработки данных
# ✅ Используйте списки для:
# - Малых наборов данных
# - Когда нужен доступ по индексу
# - Когда нужно переитерировать несколько раз
Итоги
Итератор нужен для:
- Экономии памяти — не хранит все данные
- Ленивых вычислений — считает только нужное
- Работы с большими данными — файлы, БД, API
- Цепочки трансформаций — эффективная обработка
- Асинхронности — async iterators
- Бесконечности — бесконечные последовательности
Итератор — это одна из самых мощных и часто используемых концепций в Python. Без понимания итераторов невозможно писать эффективный код.