Когда лучше использовать zip
вместо itertools.izip
?
Когда лучше использовать zip вместо izip?
Ответы (4)
Когда вы знаете, что вам понадобится полный список элементов (например, для передачи в функцию, которая изменит этот список на месте). Или когда вы хотите, чтобы аргументы, которые вы передаете zip()
, полностью оценивались в этот конкретный момент.
izip
повторно использует tuple
только в том случае, если tuple
был выпущен до начала следующей итерации, поэтому он ничего вам не дает. Тем не менее, любая потеря также тривиальна, поэтому я согласен с тем, что нет особых причин не использовать исключительно izip
, обертывая list
, если вам нужен list
; на самом деле вы можете сделать это правильно, добавив from future_builtins import zip
в код Py2, который превращает простой zip
в izip
(подготовка к переходу Py3).
- person ShadowRanger; 28.12.2015
zip
вычисляет весь список сразу, izip
вычисляет элементы только по запросу.
Одно важное отличие состоит в том, что 'zip' возвращает фактический список, а 'izip' возвращает 'izip-объект', который не является списком и не поддерживает специфические для списка функции (такие как индексирование):
>>> l1 = [1, 2, 3, 4, 5, 6]
>>> l2 = [2, 3, 4, 5, 6, 7]
>>> z = zip(l1, l2)
>>> iz = izip(l1, l2)
>>> isinstance(zip(l1, l2), list)
True
>>> isinstance(izip(l1, l2), list)
False
>>> z[::2] #Get odd places
[(1, 2), (3, 4), (5, 6)]
>>> iz[::2] #Same with izip
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'itertools.izip' object is unsubscriptable
Итак, если вам нужен список (не похожий на список объект), просто используйте 'zip'.
Кроме того, izip может быть полезен для экономии памяти или циклов.
Например. следующий код может завершиться через несколько циклов, поэтому нет необходимости вычислять все элементы комбинированного списка:
lst_a = ... #list with very large number of items
lst_b = ... #list with very large number of items
#At each cycle, the next couple is provided
for a, b in izip(lst_a, lst_b):
if a == b:
break
print a
использование zip
привело бы к вычислению всех (a, b)
пар перед входом в цикл.
Более того, если lst_a
и lst_b
очень большие (например, миллионы записей), zip(a, b)
создаст третий список с двойным пробелом.
Но если у вас небольшие списки, возможно, zip
будет быстрее.
Библиотека itertools предоставляет «итераторы» для общих функций Python. Из документации itertools: «Как zip(), за исключением того, что он возвращает итератор вместо списка». I в izip() означает «итератор».
Итераторы Python представляют собой «ленивую загрузку» последовательности, которая экономит память по сравнению с обычным списком в памяти. Таким образом, вы должны использовать itertools.izip(a, b), когда два входа a, b слишком велики, чтобы хранить их в памяти одновременно.
Посмотрите концепции Python, связанные с эффективной последовательной обработкой:
"generators" & "yield"
"iterators"
"lazy loading"
В версии 2.x, когда вам нужен список вместо итератора.
itertools.izip()
, за исключением тех случаев, когда прибыль будет чисто статистической.
- person Ignacio Vazquez-Abrams; 14.02.2011
lst = zip(lst_a, lst_b)
позволяет lst[1]
или len(lst)
. Однако для ilst = itertools.izip(lst_a, lst_n)
вам не удастся выполнить ilst[1]
или len(ilst)
.
- person Jan Vlcinsky; 22.08.2013
zip
, слишком очевидная, но все же заслуживающая внимания, заключается в том, чтоizip
возвращаетiterator
, который можно пройти только один раз. то есть вii = izip(a,b) ; f(ii) ; g(ii)
здесь пустой список[]
передается вg
. - person Causality   schedule 06.07.2016zip
в Python 3 — это функцияizip
в Python 2. В общем, Python 3 изменил большинство функций, чтобы использовать итераторы, такие как диапазон, фильтр, функции dict и т. д. - person Charles L.   schedule 13.10.2018