itertools.product是否会延迟评估其参数?
以下内容在Python 3.6中从不打印任何内容
from itertools import product, count
for f in product(count(), [1,2]):
print(f)
相反,它只是坐在那里烧坏了CPU。问题似乎在于,product
如果迭代器位于无限空间内,则永远不会返回迭代器,因为它product
首先评估完整的迭代器。鉴于product
假设应该是发电机,这令人惊讶。
我本来希望这会开始计数(到无穷大),就像这个生成器的行为(直接从docs取得):
for tup in ((x,y) for x in count() for y in [1,2]):
print(tup)
但是,尽管我的生成器立即开始计数,但使用的生成器product
根本不计数。
其他工具可以itertools
达到我的期望。例如,以下内容:
for f in takewhile(lambda x: True, count()):
print(f)
因为takewhile
懒惰,将打印数字流。
-
itertools.product
懒惰地生成其结果,但是对于参数而言并非如此。他们受到热切评价。每个可迭代的参数都首先转换为元组:参数的评估(而不是结果的产生)与文档中显示的Python实现非常相似:
... pools = [tuple(pool) for pool in args] * repeat
而在CPython实现中,
pools
是一个元组的元组:for (i=0; i < nargs ; ++i) { PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *pool = PySequence_Tuple(item); /* here */ if (pool == NULL) goto error; PyTuple_SET_ITEM(pools, i, pool); indices[i] = 0; }
之所以如此,是因为
product
有时有时需要遍历一次以上的迭代,如果将参数作为只能被使用一次的迭代器保留,则这是不可能的。实际上,您不能从
itertools.count
对象构建元组。在传递给之前,请考虑 将切片
至的合理长度。itertools.islice``product