Коли краще використовувати zip
замість itertools.izip
?
Коли краще використовувати zip
замість itertools.izip
?
zip
функція Python 3 є Python 2 izip
. Загалом Python 3 змінив більшість функцій на використання ітераторів, таких як діапазон, фільтр, функції dict тощо
Відповіді:
Коли ви знаєте, що вам потрібен повний перелік побудованих елементів (наприклад, для передачі функції, яка міняла б цей список на місці). Або коли ви хочете змусити аргументи, до яких ви передаєте, zip()
бути повністю оціненими в той конкретний момент.
izip
повторно використовує лише те, tuple
що tuple
було випущено до початку наступної ітерації, тож це вам нічого не принесе . Тим не менш, будь-яка втрата також є тривіальною, тому я погоджуюся, що є мало причин не використовувати izip
виключно, обгортання, list
якщо вам потрібно list
; ви можете зробити це «правильний» шлях, додаючи from future_builtins import zip
до py2 коду, що робить простий zip
INTO izip
(підготовка до переходу PY3).
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
це швидше.
Бібліотека itertools надає "ітератори" для загальних функцій Python. З документації itertools: "Як zip (), за винятком того, що він повертає ітератор замість списку." I в izip () означає "ітератор".
Ітератори Python - це "ліниво завантажена" послідовність, яка економить пам'ять над звичайним списком в пам'яті. Отже, ви б використовували itertools.izip (a, b), коли два входи a, b занадто великі, щоб одночасно зберігати їх у пам'яті.
Знайдіть концепції Python, пов’язані з ефективною послідовною обробкою:
"generators" & "yield"
"iterators"
"lazy loading"
У 2.x, коли вам потрібен список замість ітератора.
itertools.izip()
за винятком випадків, коли виграш буде суто статистичним.
lst = zip(lst_a, lst_b)
дозволяє lst[1]
або len(lst)
. Однак для ilst = itertools.izip(lst_a, lst_n)
вас не вдасться спробувати ilst[1]
або len(ilst)
.
zip
, занадто очевидною, але на яку все-таки варто звернути увагу, єizip
повернення,iterator
яке можна пройти лише один раз. тобто вii = izip(a,b) ; f(ii) ; g(ii)
, тут[]
передається порожній списокg
.