Генератор vs итератор: в чём разница
less_29__Generators/theory_01__Generator_vs_Iterator.md
Объясняет, что генератор — это частный случай итератора, и сравнивает их по пяти признакам: способ создания (класс с __iter__/__next__ вручную против yield или генераторного выражения), кто управляет состоянием, простота написания, способность принимать значения через send() и расход памяти. Приводится полный пример собственного класса-итератора Counter рядом с эквивалентной генераторной функцией counter.
- Класс Counter с __iter__/__next__ — итератор вручную
- def counter(n) с yield — тот же результат, но проще
- Управление состоянием: программист (итератор) vs Python (генератор)
- gen.send(10) — генератор умеет принимать значения, итератор нет
- Итоговая сравнительная таблица (5 строк)
Показать начало файла (115 строк всего)
## Определение
**Генератор** — это частный случай итератора.
## Но чем они отличаются?
### 1. По способу создания
**Итератор**:
1. **Мы пока знаем ТОЛЬКО итераторы последовательностей**
***(например, итератор списка)***
2. Чуть позже, после знакомства с ООП, мы сможем создавать итераторы со сложной логикой.
* нужно реализовать вручную два метода:
* `__iter__()` — возвращает сам итератор
* `__next__()` — возвращает следующее значение или `StopIteration`
* это больше кода
Пример собственного итератора:
```python
class Counter:
def __init__(self, n):
self.n = n
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i < self.n:
self.i += 1
return self.i
raise StopIteration
c = Counter(3)
print(next(c)) # 1
print(next(c)) # 2
print(next(c)) # 3
print(next(c, 'Итератор исчерпан')) # Итератор исчерпан
```
**Генератор**:
* создаётся автоматически:
* либо с помощью `yield`
* либо с помощью генераторного выражения
* не нужно писать класс и методы (т.е. не нужно описывать поведение итератора)
* программисту достаточно описать только логику появления следующего элемента.
Пример генератора:
```python
def counter(n):
i = 0
…