пустая переменная zip после первого использования

#python-3.x #loops #iterator

#питон #python-3.x #итератор

Вопрос:

Python 3.2

 t = (1, 2, 3)
t2 = (5, 6, 7)
z = zip(t, t2)

for x in z:
    print(x)
 

Результат:

 (1, 5)
(2, 6)
(3, 7)
 

Вводя ТОЧНО такой же цикл сразу после этого, ничего не печатается:

 for x in z:
    print(x)
 

z все еще существует как <zip object at 0xa8d48ec> . Я даже могу переназначить t , t2 чтобы снова заархивировать, но тогда это работает только один раз и только один раз, снова.

Это так, как это должно работать? В документах об этом ничего не упоминается.

Ответ №1:

Вот как это работает в python 3.x. В python2.x zip возвращается список кортежей, но для python3.x zip itertools.izip он ведет себя так же, как в python2.x. Чтобы восстановить поведение python2.x, просто создайте список из zip выходных данных:

 z = list(zip(t,t2))
 

Обратите внимание, что в python3.x многие встроенные функции теперь возвращают итераторы, а не списки ( map , zip , filter )

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

1. немного поздно для вечеринки, но это просто поставило меня в тупик. Кажется сумасшедшим, что вы не можете вернуться к началу итератора, и простое использование zip имеет изменяемый эффект. Нелегко понять, как Python заставляет верить…

2. @NeilWalker — Возможно, нет, но есть много действительно больших преимуществ для ленивой итерации, которые позволяют итераторы python (рассмотрим любые потоковые данные, не подлежащие поиску). Вы можете выполнять большую обработку с очень небольшими системными затратами по сравнению с мировоззрением «все — список».

Ответ №2:

Потому zip что возвращает итератор в Python 3.x. Если вы хотите использовать его повторно, сделайте его list первым:

 z = list(zip(t, t2))
 

Ответ №3:

zip возвращает итератор (в Python 3). Вы можете выполнить итерацию по итератору только один раз. Итератор не исчезает, когда в нем нет элементов, но повторная итерация по нему дает 0 элементов. Если вам нужен список, позвоните list по нему:

 z = list(zip(t, t2))