所有讨论都是关于python 3.1.2;请参阅Python docs了解我的问题来源。
我知道zip
的作用;我只是不明白为什么它可以像这样实现:
def zip(*iterables):
# zip('ABCD', 'xy') --> Ax By
iterables = map(iter, iterables)
while iterables:
yield tuple(map(next, iterables))
假设我打电话给zip(c1, c2, c3)
。如果我理解正确,iterables最初是元组(c1,c2,c3)。
行iterables = map(iter, iterables)
将它转换为迭代器,如果遍历,它将返回iter(c1),iter(c2),iter(c3)。
在循环内部,map(next, iterables)
是一个迭代器,如果迭代,它将返回next(iter(c1))
,next(iter(c2))
和next(iter(c3))
。 tuple
调用将其转换为(next(iter(c1)), next(iter(c2)), next(iter(c3))
,据我所知,在第一次调用时耗尽其参数(iterables
)。我不明白while
循环如何继续,因为它检查iterables
;如果确实继续,为什么tuple
调用不返回空元组(迭代器已用完)。
我确定我错过了很简单的事情......
答案 0 :(得分:9)
看起来这是文档中的错误。 “等效”代码可以在python2中运行,但不能在python3中运行,它会进入无限循环。
最新版本的文档存在同样的问题:http://docs.python.org/release/3.1.2/library/functions.html
看起来更改61361是个问题,因为它合并了python 2.6中的更改,而没有验证它们对python3是否正确。
看起来主干文档集上不存在该问题,但您可能应该在http://bugs.python.org/报告有关它的错误。
答案 1 :(得分:7)
似乎这段代码应该被读作python-2.x代码。它甚至在py3k中都没有正常运行。
python-2.x中发生的是map
返回迭代器列表,当调用next
时,它返回迭代器元素,这些元素组合成元组。所以,给定
>>> zip('ABCD', 'xy')
iterables是一个包含2个迭代器的列表,在while循环中的每次迭代中,迭代器的下一个(第一个剩余的)元素被消耗(''A'
和'x'
等),并且产生为元组的元素,然后在产生最后的元素之后,(在第3次迭代中)引发StopIteration
停止生成器。 while iterables
始终为True
。