Генератор и одноразовый итератор в Python
@python_quizРазберем этот квиз
Код из квиза:

Кратко: nums — это генератор (генераторное выражение). Генераторы — одноразовые итераторы: как только вы проходите по ним, элементы «исчерпываются».
Что происходит по шагам
- Создается генератор, который будет выдавать 0, 1, 2 по одному при итерации.
- Вызов sum(nums) начинает итерацию по генератору и вычисляет сумму 0 + 1 + 2 = 3. При этом генератор полностью исчерпывается.
- После этого list(nums) пытается собрать оставшиеся элементы генератора, но так как их больше нет, получается пустой список.
Фактический вывод программы:

Разбор вариантов ответов (логика)
- Вариант с "3 [0, 1, 2]" предполагает, что генератор можно пройти два раза подряд, не теряя элементов — это неверное предположение для генераторов. Такое поведение было бы верным для списка, но не для одноразового итератора.
- Вариант с "3 []" соответствует реальному поведению: sum исчерпывает генератор, list получает пустой итератор.
- Вариант с "0 [0, 1, 2]" мог бы случиться, если бы sum применялся к пустому итератору, а затем list строился из исходных значений — но в данном коде sum получает все элементы.
- Вариант с "0 []" означал бы, что генератор сразу пуст или sum вернул 0 (например, на пустом итераторе), но это не соответствует генератору range(3).
Демонстрация альтернатив и решений
- Если нужно сначала вычислить сумму, но сохранить элементы для последующих операций, превратите генератор в список:

- Если вы хотите "раздвоить" итератор, можно использовать itertools.tee (но учтите накладные расходы по памяти):

Замечания по производительности и памяти
- Преобразование в список сохраняет все элементы в памяти — удобно, если данных немного.
- Генераторы полезны для ленивой обработки больших потоков данных, но их одноразовость нужно учитывать: если нужна многократная итерация, используйте список или создавайте новый генератор при необходимости.
- itertools.tee может помочь, но дублирование состояния может потребовать дополнительной памяти.
Вывод
- Генераторное выражение даёт одноразовый итератор. В примере sum полностью исчерпывает генератор, поэтому второй вызов list возвращает пустой список. Если требуется повторное использование элементов, сперва сохраните их (например, в список) или используйте подходы вроде itertools.tee с пониманием их ограничений.