以下面的例子为例:

>>> for item in [i * 2 for i in range(1, 10)]:
    print item


2
4
6
8
10
12
14
16
18
[i * 2 for i in range(1, 10)] 是每次通过循环计算,还是只计算一次并存储? (另外,表达式中该部分的正确名称是什么?)

我想要这样做的一个原因是我只希望该列表理解的结果在循环中可用。

最佳答案

for i in <whatever>: <loopbody> 的一个很好的翻译,准确地显示了它对 任何 <whatever> 任何 <loopbody> 的作用:

_aux = iter(<whatever>)
while True:
  try: i = next(_aux)
  except StopIteration: break
  <loopbody>

除了我在这里命名为 _aux 的伪变量实际上仍未命名。

因此, <whatever> 总是只被评估一次(从中获取 iter() )并且结果迭代器是 next ed,直到它用完(除非 break 中有一些 <loopbody> )。

使用 listcomp,正如您所使用的,评估会生成一个 list 对象(在您的代码示例中它保持未命名)。在非常相似的代码中:
for item in (i * 2 for i in range(1, 10)): ...

使用 genexp 而不是 listcomp(在语法上,圆括号而不是 listcomp 的方括号),实际上是 next() 完成了大部分工作(推进 i 并将其加倍),而不是在构建时集中所有工作——这需要占用更少的临时内存,并且如果循环主体合理地可能提前 break 输出,则可以节省时间,但除了在这种特殊情况下(非常紧张的内存或可能提前终止循环),listcomp 通常可能(稍微快一点)更快。

关于Python:如果迭代器是表达式,是否每次都计算?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3137443/

10-12 13:05