【问题标题】:When is it better to use zip instead of izip?什么时候使用 zip 而不是 izip 更好?
【发布时间】:2011-06-26 18:16:39
【问题描述】:

什么时候最好使用zip 而不是itertools.izip

【问题讨论】:

  • 支持zip 的一个原因,太明显但仍然值得指出,是izip 返回一个iterator,它只能被遍历一次。即在ii = izip(a,b) ; f(ii) ; g(ii) 中,这里将一个空列表[] 传递给g
  • 仅供参考,Python 3 的 zip 函数是 Python 2 的 izip。一般来说,Python 3 将大多数函数更改为使用迭代器,例如 range、filter、dict 函数等

标签: python-2.7 python-2.x itertools


【解决方案1】:

zip 一次计算所有列表,izip 仅在请求时计算元素。

一个重要的区别是'zip'返回一个实际的列表,'izip'返回一个'izip object',它不是一个列表并且不支持特定于列表的功能(例如索引):

>>> 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_alst_b 非常大(例如数百万条记录),zip(a, b) 将构建第三个带有双倍空格的列表。

但如果您的列表很小,也许zip 更快。

【讨论】:

  • 你是对的。我怀着良好的意愿开始,然后陷入了理论的东西......
【解决方案2】:

当您知道您需要构建完整的项目列表时(例如,用于传递给将就地修改该列表的函数)。或者,当您想强制传递给 zip() 的参数在该特定点被完全评估时。

【讨论】:

  • 在第一种情况下使用 izip 会不会更好,因为它会重用元组并且没有真正的理由不使用 izip 吗?
  • @user1815201: izip 仅在tuple 在下一次迭代开始之前发布时才重用tuple,因此它不会为您带来任何好处。也就是说,任何损失也是微不足道的,所以我同意没有理由不专门使用izip,如果您需要list,请使用list;您实际上可以通过将from future_builtins import zip 添加到Py2 代码来以“正确”的方式执行此操作,这使得普通的zip 变为izip(为Py3 转换做准备)。
【解决方案3】:

itertools 库为常见的 Python 函数提供“迭代器”。来自 itertools 文档,“像 zip() 只是它返回一个迭代器而不是一个列表。” izip() 中的 I 表示“迭代器”。

Python 迭代器是一个“延迟加载”序列,它比常规内存列表节省内存。因此,当两个输入 a、b 太大而无法一次保存在内存中时,您将使用 itertools.izip(a, b)。

查找与高效顺序处理相关的 Python 概念:

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

【讨论】:

  • 解释得很好。
【解决方案4】:

在 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)
猜你喜欢
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
  • 2012-01-15
  • 2013-05-15
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
相关资源
最近更新 更多