当前位置: 首页 > 面试题库 >

itertools.product是否会延迟评估其参数?

丁雅懿
2023-03-14
问题内容

以下内容在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



 类似资料:
  • 考虑具有用户偏好系统的应用程序的以下用例: 我们想得到首选项MyFlag的布尔值 在最佳情况下,我们希望从当前用户的设置中获得它 如果失败,我们希望从默认设置中获取MyFlag<如果失败,抛出。 设置在服务器上。此连接很慢,可能会失败。 获取设置和获取首选项也可能失败。 所以让我们使用javas选项: 这里的问题是连接可能非常慢。当<代码>。orElse(slowlyGet…) slowlyGet

  • 问题内容: 例如,如果我有以下语句: 如果foo1为true,python将检查foo2的条件吗? 问题答案: 是的,Python懒惰地评估布尔条件。 该文件说, 表达式x和y首先计算x;如果x为假,则返回其值;否则,将评估y并返回结果值。 表达式x或y首先计算x; 如果x为true,则返回其值;否则,将评估y并返回结果值。

  • 问题内容: 我的问题很简单。 循环是否评估它每次使用的参数? 如: python是否为该循环的每次迭代创建300个项目的列表? 如果是这样,这是避免这种情况的方法吗? 这样的代码示例也是如此。 是每一次应用反向过程,还是在每次迭代中计算长度?(我同时要求python2和python3) 如果不是,Python在迭代时如何评估可迭代的更改? 问题答案: 不用担心,迭代器只会被评估一次。它最终大致等同

  • 问题内容: 我知道Java在这种情况下具有智能/惰性评估: 但是关于: 即使返回true 也被调用? 问题答案: 在Java(和其他类似C的语言)中,这称为 短路评估 。* 是的,在第二个示例中总是被调用。也就是说,除非编译器/ JVM可以确定它没有可观察到的副作用,否则在这种情况下它可以选择进行优化,但是无论如何您都不会注意到它们之间的差异。 两者截然不同; 前者本质上是一种优化技术,而第二种则

  • 问题内容: 可以安全地假设函数参数在Python中是从左到右求值的吗? 参考文献指出,这种情况会发生,但是也许有某种方法可以更改此顺序,这可能会破坏我的代码。 我想做的是为函数调用添加时间戳: 我知道我可以按顺序评估参数: 但是它看起来不太优雅,因此如果可以依靠它,我宁愿采用第一种方法。 问题答案: 是的,Python始终从左到右评估函数参数。 据我所知,这适用于任何逗号分隔的列表:

  • 问题内容: 我想知道JavaScript是否具有C#中的&&运算符之类的“短路”评估。如果没有,我想知道是否有一种合理的解决方法可以采用。 问题答案: 是的,JavaScript具有“短路”评估。