Найти в Дзене

Генераторы и итераторы в Python: как писать эффективный код

  Привет! Сегодня поговорим о *генераторах и итераторах* — мощном инструменте Python, который позволяет работать с **огромными данными** без лишней памяти.  ---  1. Итераторы: что это и зачем нужны? *Итератор* — это объект, который можно *перебрать в цикле* (`for`), но он не загружает все элементы в память сразу.  Любой объект с методами `__iter__()` и `__next__()` является **итератором**.  Пример: создадим итератор вручную  class Counter:   def __init__(self, start, end):     self.current = start     self.end = end   def __iter__(self):     return self # Итератор должен вернуть сам себя   def __next__(self):     if self.current >= self.end:       raise StopIteration # Завершаем итерацию     value = self.current     self.current += 1     return value counter = Counter(1, 5) for num in counter:   print(num) **Вывод:**  1  2  3  4  ``` Объект `Counter` можно **перебирать в цикле!  --- 2. Генераторы: ленивые итераторы **Генератор** — это функция, которая запоминает свое сост

 

Привет! Сегодня поговорим о *генераторах и итераторах* — мощном инструменте Python, который позволяет работать с **огромными данными** без лишней памяти. 

--- 

1. Итераторы: что это и зачем нужны?

*Итератор* — это объект, который можно *перебрать в цикле* (`for`), но он не загружает все элементы в память сразу. 

Любой объект с методами `__iter__()` и `__next__()` является **итератором**. 

Пример: создадим итератор вручную 

class Counter:

  def __init__(self, start, end):

    self.current = start

    self.end = end

  def __iter__(self):

    return self # Итератор должен вернуть сам себя

  def __next__(self):

    if self.current >= self.end:

      raise StopIteration # Завершаем итерацию

    value = self.current

    self.current += 1

    return value

counter = Counter(1, 5)

for num in counter:

  print(num)

**Вывод:** 

```

Объект `Counter` можно **перебирать в цикле! 

---

2. Генераторы: ленивые итераторы

**Генератор** — это функция, которая запоминает свое состояние. Он использует `yield`, а не `return`. 

Пример: простой генератор

def my_generator():

  print("Первый шаг")

  yield 1

  print("Второй шаг")

  yield 2

  print("Третий шаг")

  yield 3

gen = my_generator()

print(next(gen)) # Первый шаг -> 1

print(next(gen)) # Второй шаг -> 2

print(next(gen)) # Третий шаг -> 3

```

Генератор не выполняет весь код сразу, а помнит, где остановился. 

---

3. Генераторы вместо списков (экономия памяти)** 

Обычный список (много памяти)

numbers = [x**2 for x in range(10**6)] # Огромный список

print(sum(numbers))

```

⏳ **Занимает много памяти!** 

Генератор (мало памяти)

numbers = (x**2 for x in range(10**6)) # Генератор вместо списка

print(sum(numbers))

```

✅ Работает быстрее и почти не занимает память! 

---

4. Бесконечные генераторы** 

Пример: бесконечная последовательность 

def infinite_numbers():

  num = 0

  while True:

    yield num

    num += 1

gen = infinite_numbers()

print(next(gen)) # 0

print(next(gen)) # 1

print(next(gen)) # 2

```

Генераторы позволяют работать с бесконечными потоками данных. 

---

5. Практическое применение

| Где используются? | Как помогают? |

|-------------------|---------------|

| Чтение файлов | Читают строки построчно, без загрузки всего файла |

|Работа с API | Запрашивают данные постепенно, без перегрузки |

| Обработка больших данных| Перебирают миллионы записей без расхода памяти |

---

Заключение

✅ **Итераторы** позволяют писать **гибкие классы**. 

✅ **Генераторы** экономят **память и ускоряют код**. 

✅ Они **незаменимы при работе с большими данными**. 

Ты уже использовал генераторы? Пиши в комментариях! 

***#python #генераторы #оптимизация***