Страницы

Поиск по вопросам

среда, 31 октября 2018 г.

Обнуление кортежа в Python после применения sum

Вот так вывод кортежа происходит нормально:
l = (i for i in range(1,9) if i%2 == 1) print(*l)
Получаем на выводе 1 3 5 7
Но если попытаться сначала вывести сумму кортежа, то сумма выведется, но сам кортеж уже не отобразится:
l = (i for i in range(1,9) if i%2 == 1) print(sum(l)) print(*l)
На выводе получим 16 и пустую строку.
Если делать то же самое не с кортежем, а со списком, то все нормально. В чем причина странного поведения кортежа?


Ответ

Конструкция ... for ... in ... в круглых скобках порождает не кортеж, а генератор — объект, который используется для итерации всяких последовательностей. Ключевое отличие от списка — непосредственные вычисления производятся только по мере надобности, при получении каждого следующего элемента вызовом функции next. Итератор одноразовый однажды получив все значения, он будет пуст. Собственно говоря, это у вас и происходит вначале при вычислении суммы, затем уже ничего не остаётся для вывода на экран.
Давайте рассмотрим пример.
l = [2**i for i in range(2, 10)] g = (2**i for i in range(2, 10))
В первом случае все возведения в степень будут произведены в момент создания списка, а все созданные числа будут храниться в памяти. Может быть не очень рационально, если они будут использоваться только по одному разу.
Во втором случае, напротив, операция возведения в степень производится непосредственно в момент получения очередного элемента. Например, так
next(g) # вернёт 4 при первом вызове, затем 8 при втором, ...
Когда последовательность заканчивается, вызов next окончится исключением StopIteration. Это даёт однозначно выявить конец.

Комментариев нет:

Отправить комментарий