我的问题只是为了学习目的,而且只在python3.x上。在现实生活中,我将使用zip,因为python3zip的作用与python2-izip相同(即返回一个生成器,而不是真正的东西)。在
在python2中,izip本质上等同于下面的代码(从izip中选取,加上一些调试代码)
def izip(*iterables):
iterators = map(iter, iterables)
n = 0
while iterators:
x = tuple(map(next, iterators))
print("at n={}, x={} ".format(n, x))
yield x
n += 1
if n > 10: break
Python2很好。izip('abc', 'ABC')
的输出是:
Python3进入了一个无限循环。原因在this thread中解释。但还有一点我无法理解:python3只产生第一个元组。这是同一程序的输出。为什么bs和cs没有出现?公司名称:
at n=0, x=('a', 'A')
('a', 'A')
at n=1, x=()
()
at n=2, x=()
()
at n=3, x=()
() etc.
我的两个问题是为什么Python会这样?如何让这些代码生效呢?在
问题在于python2和python3之间
map
的不同行为,特别是在对map
(iterators = map(iter, iterables)
)的第一次调用中。在在python3中,
map
返回生成器(或类似生成器的对象),而在python2中,它是一个列表。这意味着在第一次调用tuple(map(next, iterators))
之后,iterators
生成器将被完全消耗,因此在下一次迭代中,不再需要再使用迭代器了。在如果你改变了:
收件人:
^{pr2}$(这可以说是更好的
iterators = [ iter(it) for it in iterables ]
)正如您所指出的,它现在进入了一个无限循环。同样,问题在于
map
函数,但这次是在第二次调用中。在首先,让我们了解这个实现在python2中是如何工作的。尽管有一个
while iterators
循环,但循环不会因条件为false而中断,而是由于对next
的一个调用引发StopIteration异常。此异常被传播到调用方的循环,它正确地理解不再有结果。在这样执行可能会很直观:
现在,
map
的行为在python3中也发生了变化。它不是提高产量,而是“削减”产出:不引发StopIteration会导致无限循环。在
解决方案是使用列表理解,它会传播StopIteration异常。在
经验教训:列出理解(和生成器表达式)should be favoredover
map
,filter
,等等相关问题 更多 >
编程相关推荐