什么时候使用zip
代替更好itertools.izip
?
什么时候使用zip
代替更好itertools.izip
?
zip
功能是Python 2的功能izip
。一般而言,Python 3更改了大多数函数以使用迭代器,例如范围,过滤器,字典函数等
Answers:
当您知道要构建的项目的完整列表时(例如,传递给可以就地修改该列表的函数)。或者,当您想强制传递的参数zip()
在该特定点被完全评估时。
izip
仅重复使用tuple
,如果tuple
被释放的下一次迭代开始前,所以它不会获得你任何东西。话虽如此,任何损失也是微不足道的,因此我同意没有理由不izip
单独使用,list
如果需要的话请使用list
; 实际上你可以通过添加这样做的“正确”的方式from future_builtins import zip
来的Py2代码,这使得纯zip
进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
使用zip
会在进入周期之前计算所有 (a, b)
夫妇。
此外,如果lst_a
和lst_b
非常大(例如,数百万条记录),zip(a, b)
将建立第三个具有双倍空格的列表。
但是,如果您的清单较小,则可能zip
会更快。
在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)
。
itertools库为常见的Python函数提供了“迭代器”。从itertools文档中,“类似于zip(),但它返回的是迭代器而不是列表。” izip()中的I表示“迭代器”。
Python迭代器是一个“延迟加载”序列,可以在常规内存列表中节省内存。因此,如果两个输入a,b太大而无法一次存储在内存中,则可以使用itertools.izip(a,b)。
查找与有效顺序处理有关的Python概念:
"generators" & "yield"
"iterators"
"lazy loading"
zip
(太明显了,但仍然值得指出)是izip
返回一个iterator
只能被遍历一次的。即在ii = izip(a,b) ; f(ii) ; g(ii)
这里,一个空列表[]
被传递给g
。