Поведение генераторов в Python при повторном чтении
@python_quizРазберем этот квиз
Исходный код, который разбираем:

Что выведет этот код
При выполнении увидите:

Короткое объяснение
Генератор в Python — это итератор, который вычисляет значения лениво и не хранит их. Когда вы проходите по генератору (например, с помощью list()), он выдаёт элементы один за другим. После того как все элементы были выданы, генератор считается исчерпанным — повторная попытка пройти по нему не вернёт значений.
То есть первая команда list(it) перебирает и «съедает» все элементы генератора, а вторая уже получает пустую последовательность.
Разбор возможных вариантов (логика)
- Оба списка с элементами [0, 1, 4]: могло бы быть, если бы
itне был итератором или если бы вы заново создавали генератор перед вторым вызовом. - Первый [0, 1, 4], второй пустой: именно это происходит для генератора, потому что он исчерпывается после первого прохода.
- Первый пустой, второй [0, 1, 4]: такой результат возможен только при неправильном порядке вызовов или если первый проход происходил раньше (но в представленной программе первый list() явно до второго).
- Оба пустые: такое могло бы случиться, если генератор уже был исчерпан до этих вызовов.
Как получить два раза одинаковые значения
Если нужно получить список значений дважды, есть несколько подходов:
- Преобразовать генератор в список сразу:

- Создавать новый генератор при каждом проходе:

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

Учтите: tee может буферизовать элементы в памяти, если чтение двух копий происходит в разное время.
Вывод
Генераторы — удобный способ ленивых вычислений, но они одноразовые. Если вам нужно многократное прохождение по тем же данным, заранее материализуйте их в коллекцию или явно создавайте новый генератор при каждом проходе. Для специфических сценариев пригодится itertools.tee, но его поведение и стоимость по памяти следует учитывать.