Почему распаковка удаляет содержимое объекта - PullRequest
0 голосов
/ 08 февраля 2019

Может ли кто-нибудь объяснить мне, почему при разархивировании заархивированного объекта (z1) исходный объект (z1) остается пустым?

mutants = ['charles xavier', 'bobby drake',
           'kurt wagner', 'max eisenhardt', 'kitty pride']
powers = ['telepathy', 'thermokinesis',
'teleportation', 'magnetokinesis', 'intangibility']

z1 = zip(mutants, powers)

print(*z1)

print(*z1)

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

zip возвращает итератор, и вы можете использовать итератор только один раз.

Если количество элементов мало, вы можете создать список или кортеж с элементами,или вы можете использовать itertools.tee для создания нескольких независимых итераторов из оригинала:

import itertools

z1, z2 = itertools.tee(zip(mutants, powers), 2)

print(*z1)
print(*z2)

Результат:

('charles xavier', 'telepathy') ('bobby drake', 'thermokinesis') ('kurt wagner', 'teleportation') ('max eisenhardt', 'magnetokinesis') ('kitty pride', 'intangibility')
('charles xavier', 'telepathy') ('bobby drake', 'thermokinesis') ('kurt wagner', 'teleportation') ('max eisenhardt', 'magnetokinesis') ('kitty pride', 'intangibility')
0 голосов
/ 08 февраля 2019

Он не удаляется.

Если вы выполните print(z1), вы увидите, что он печатает почтовый объект .Это потому, что zip не создает tuple или list, а скорее итератор .

Итератор - это то, что генерирует значения по требованию.В этом случае объект zip генерирует пары, взятые из входных данных;а именно списки mutants и powers.Чтобы увидеть это в действии, после назначения z1 вы можете позвонить print(next(z1)), что заставит z1 сгенерировать следующую пару и распечатать ее;в этом случае ('charles xavier', 'telepathy').

Если вы продолжаете вызывать next(z1), он будет перебирать два списка, пока не достигнет конца.В этот момент у него не осталось данных для чтения, поэтому, если вы попытаетесь вызвать next(z1) снова, это вызовет исключение StopIteration, которое означает, что итерируемое значение исчерпано .

И наоборот, если бы вы сделали что-то вроде t1 = tuple(z1), вы сможете звонить print(*t1) столько раз, сколько захотите.Однако, если вы это сделаете, а затем попытаетесь позвонить t2 = tuple(z1), вы поймете, что t2 пусто.Это по той же причине, что и приведенная выше: сборка t1 из z1 уже исчерпала ее, поэтому, когда t2 пытается получить значения из z1, он сразу же набирает StopIteration и, таким образом, генерирует пустое tuple.

...