🐛 Типичные ошибки

❌ Ошибка 1: повторное использование исчерпанного итератора

numbers = [1, 2, 3]
iterator = iter(numbers)

print(list(iterator))  # [1, 2, 3]
print(list(iterator))  # []

Почему возникает: итератор запоминает позицию и после полного прохода становится пустым. Повторный перебор даёт пустую последовательность.

✅ Исправление

numbers = [1, 2, 3]

# Создаём новый итератор для каждого прохода
print(list(iter(numbers)))
print(list(iter(numbers)))

❌ Ошибка 2: вызов next() на списке, а не на итераторе

numbers = [1, 2, 3]
print(next(numbers))  # TypeError

Сообщение об ошибке: TypeError: 'list' object is not an iterator

Почему возникает: список — итерируемый объект, но не итератор. У него есть __iter__(), но нет __next__().

✅ Исправление

numbers = [1, 2, 3]
iterator = iter(numbers)
print(next(iterator))  # 1

❌ Ошибка 3: путаница между списковым включением и генераторным выражением

# Хотели генератор, а получили список
squares = [x ** 2 for x in range(5)]
print(type(squares))  # <class 'list'>

Почему возникает: квадратные скобки создают список, круглые — генератор. Если нужна экономия памяти, нужны круглые скобки.

✅ Исправление

squares = (x ** 2 for x in range(5))
print(type(squares))  # <class 'generator'>

❌ Ошибка 4: игнорирование StopIteration при ручном вызове next()

numbers = [1, 2]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))  # StopIteration

Почему возникает: элементы закончились, а next() не получил значение по умолчанию и не обёрнут в try-except.

✅ Исправление

numbers = [1, 2]
iterator = iter(numbers)

while True:
    value = next(iterator, None)
    if value is None:
        break
    print(value)

❌ Ошибка 5: передача одного генератора в несколько функций

values = (x for x in range(10))

print(any(v > 5 for v in values))  # True
print(all(v >= 0 for v in values))  # True, но ложно: генератор исчерпан

Почему возникает: второе выражение all(v >= 0 for v in values) обходит уже пустой генератор, поэтому всегда возвращает True.

✅ Исправление

values = range(10)  # итерируемый объект можно перебирать заново
print(any(v > 5 for v in values))
print(all(v >= 0 for v in values))