3

有人可以解释为什么这些在 Python 2.7.4 中输出不同的东西吗?它们在 python 3.3.1 中输出相同的东西。我只是想知道这是否是在 3 中修复的 2.7 中的错误,或者是否是由于语言的某些更改。

>>> for (i,j),k in zip(groupby([1,1,2,2,3,3]), [4,5,6]):
...     print list(j)
... 
[]
[]
[3]
>>> for i,j in groupby([1,1,2,2,3,3]):
...     print list(j)
... 
[1, 1]
[2, 2]
[3, 3]
4

1 回答 1

7

这不是一个错误。它与 groupby 迭代何时被消耗有关。使用 python3 尝试以下操作,您将看到相同的行为:

from itertools import groupby
for (i,j),k in list(zip(groupby([1,1,2,2,3,3]), [4,5,6])):
    print (i,list(j),k)

请注意,如果您删除 external list,那么您将获得您期望的结果。这里的“问题”是 grouper 对象(在 中返回j)是一个迭代,只要它们相同,它就会产生元素。它不提前知道它将产生什么或有多少元素。它只是接收一个可迭代对象作为输入,然后从该可迭代对象中产生。如果您继续前进到下一个“组”,那么在您有机会查看元素之前,迭代最终会被消耗掉。这是一个设计决策,允许groupby对产生任意(甚至无限)数量的元素的迭代进行操作。

在 python2.x 中,zip将创建一个列表,在循环开始之前有效地通过每个“组”。在这样做的过程中,它最终消耗了由groupby. 这就是为什么您只报告列表中的最后一个元素。python2.x 的修复是使用itertools.izip而不是zip. 在 python3.x 中,izip变成了 builtin zip。如我所见,在此脚本中支持两者的唯一方法是通过以下方式:

from __future__ import print_function
from itertools import groupby
try:
    from itertools import izip
except ImportError:  #python3.x
    izip = zip

for (i,j),k in izip(groupby([1,1,2,2,3,3]), [4,5,6]):
    print (i,list(j),k)
于 2013-05-16T22:13:47.200 回答