Python:如果迭代器是一个表达式,那么每次都计算它吗?

Nic*_*ner 4 python iterator loops

请看以下示例:

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


2
4
6
8
10
12
14
16
18
Run Code Online (Sandbox Code Playgroud)

[i * 2 for i in range(1, 10)]计算每循环一次,或者只是一次,存储在哪里?(另外,表达式中该部分的正确名称是什么?)

我想要这样做的一个原因是我只希望循环中可以获得该列表理解的结果.

Ale*_*lli 5

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

_aux = iter(<whatever>)
while True:
  try: i = next(_aux)
  except StopIteration: break
  <loopbody>
Run Code Online (Sandbox Code Playgroud)

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

所以,<whatever>总是被评估只是一次(获得一个iter()从它),并将所得迭代器next编着,直到耗尽(除非有一些break<loopbody>).

使用listcomp,如您所使用的那样,评估会生成一个list对象(在您的代码示例中仍然未命名).在非常相似的代码中:

for item in (i * 2 for i in range(1, 10)): ...
Run Code Online (Sandbox Code Playgroud)

使用genexp而不是listcomp(在语法上,圆括号而不是listcomp的方括号),它next()实际上是完成大部分工作(推进i和加倍),而不是在施工时将所有工作集中在一起 - 这会占用更少的工作量临时存储器,并且如果循环体可能合理地break提前输出可以节省时间,但除了在这样的特殊条件下(非常紧密的存储器或可能早期的循环终止),listcomp通常可以(通过一点点)更快.