Генераторное выражение: список внутри запоминается сразу, условие — нет array = [1, 8, 15] result = [x for x in array if x > 5] array = [100, 200] print(result)

Этот код печатает [8, 15] — array перезаписали, но result уже построен, тут вопросов нет. Ловушка в другом варианте, который дают на собеседовании чаще:

array = [1, 8, 15] gen = (x for x in array if x > 5) array = [1, 8, 15, 100] print(list(gen))

Здесь результат — [8, 15], хотя array после присваивания стал длиннее.

Причина в том, что в генераторном выражении немедленно вычисляется только самый внешний итерируемый объект — тот, что идёт сразу после первого for. Python вызывает iter(array) в момент создания генератора и запоминает именно этот список из трёх элементов. Условие if x > 5 и всё, что идёт после первого for — ленивое, выполняется только при итерации.

Если переменная array внутри генератора используется не на верхнем уровне, а во вложенном for (например, (y for x in range(3) for y in array)), то array читается лениво — и подмена снаружи уже повлияет на результат. Это и спрашивают следом: «а если array во втором for?»

Разница между списковым включением и генератором тут не в лени вычисления элементов, а в том, что ссылка на первый итерируемый объект фиксируется сразу в обоих случаях — просто для списка это не создаёт иллюзии, потому что весь список уже материализован.

Тренажёр: 1900+ вопросов и задач, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки