Коли краще використовувати zip замість zip?


82

Коли краще використовувати zipзамість itertools.izip?


Однією з причин на користь zip, занадто очевидною, але на яку все-таки варто звернути увагу, є izipповернення, iteratorяке можна пройти лише один раз. тобто в ii = izip(a,b) ; f(ii) ; g(ii), тут []передається порожній список g.
Причинність

6
FYI, zipфункція Python 3 є Python 2 izip. Загалом Python 3 змінив більшість функцій на використання ітераторів, таких як діапазон, фільтр, функції dict тощо
Чарльз Л.

Відповіді:


44

Коли ви знаєте, що вам потрібен повний перелік побудованих елементів (наприклад, для передачі функції, яка міняла б цей список на місці). Або коли ви хочете змусити аргументи, до яких ви передаєте, zip()бути повністю оціненими в той конкретний момент.


1
Чи не було б краще використовувати izip у першому випадку як його швидший, оскільки він повторно використовує кортеж, і немає жодної реальної причини не використовувати izip?
користувач1815201

1
@ user1815201: izipповторно використовує лише те, tupleщо tupleбуло випущено до початку наступної ітерації, тож це вам нічого не принесе . Тим не менш, будь-яка втрата також є тривіальною, тому я погоджуюся, що є мало причин не використовувати izipвиключно, обгортання, listякщо вам потрібно list; ви можете зробити це «правильний» шлях, додаючи from future_builtins import zipдо py2 коду, що робить простий zipINTO izip(підготовка до переходу PY3).
ShadowRanger

99

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

using zipобчислив би всі (a, b) пари до вступу в цикл.

Більше того, якщо lst_aі lst_bвони дуже великі (наприклад, мільйони записів), zip(a, b)складемо третій список із подвійним пробілом.

Але якщо у вас є невеликі списки, можливо, zipце швидше.


9
Ти маєш рацію. Я почав з добрих намірів, а потім впав у теоретичні речі ...
Дон

6

Бібліотека itertools надає "ітератори" для загальних функцій Python. З документації itertools: "Як zip (), за винятком того, що він повертає ітератор замість списку." I в izip () означає "ітератор".

Ітератори Python - це "ліниво завантажена" послідовність, яка економить пам'ять над звичайним списком в пам'яті. Отже, ви б використовували itertools.izip (a, b), коли два входи a, b занадто великі, щоб одночасно зберігати їх у пам'яті.

Знайдіть концепції Python, пов’язані з ефективною послідовною обробкою:

"generators" & "yield"
"iterators"
"lazy loading"

Гарно пояснив.
Рахул

5

У 2.x, коли вам потрібен список замість ітератора.


Чи можете ви навести приклад, де це може статися?
Neil G

3
Не зовсім. Ось чому я, як правило, віддаю перевагу itertools.izip()за винятком випадків, коли виграш буде суто статистичним.
Ігнасіо Васкес-Абрамс

2
Один із випадків, коли вам потрібен список, - це коли ви плануєте отримати доступ до елементів результату за індексом або потрібно знайти загальну довжину. lst = zip(lst_a, lst_b)дозволяє lst[1]або len(lst). Однак для ilst = itertools.izip(lst_a, lst_n)вас не вдасться спробувати ilst[1]або len(ilst).
Ян Влчинський
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.