Python:函数foo()在" for foo()"循环多次调用?

时间:2016-04-13 09:34:53

标签: python python-3.x for-loop

在循环的每次重复中都调用了foo()吗?

for num in foo():
    # Do something

如果效率低下,这段代码会更好吗?

l = foo()
for num in l:
    # Do something

1 个答案:

答案 0 :(得分:3)

没有。在foo()中只调用一次。可以预期前者比后者略快。此外,list是内置函数/类型的名称,您不应将其用作变量名。

您可以使用Python字节码反汇编程序dis.dis来查找CPython生成的字节码:

>>> import dis
>>> dis.dis(compile('for num in foo():pass', '', 'exec'))
  1           0 SETUP_LOOP              17 (to 20)
              3 LOAD_NAME                0 (foo)
              6 CALL_FUNCTION            0 (0 positional, 0 keyword pair)
              9 GET_ITER
        >>   10 FOR_ITER                 6 (to 19)
             13 STORE_NAME               1 (num)
             16 JUMP_ABSOLUTE           10
        >>   19 POP_BLOCK
        >>   20 LOAD_CONST               0 (None)
             23 RETURN_VALUE

在上面的字节码中,循环体从10 FOR_ITER开始,一直持续到19 POP_BLOCK。与:比较:

>>> dis.dis(compile('l = foo()\nfor num in list:pass', '', 'exec'))
  1           0 LOAD_NAME                0 (foo)
              3 CALL_FUNCTION            0 (0 positional, 0 keyword pair)
              6 STORE_NAME               1 (l)

  2           9 SETUP_LOOP              14 (to 26)
             12 LOAD_NAME                1 (l)
             15 GET_ITER
        >>   16 FOR_ITER                 6 (to 25)
             19 STORE_NAME               2 (num)
             22 JUMP_ABSOLUTE           16
        >>   25 POP_BLOCK
        >>   26 LOAD_CONST               0 (None)
             29 RETURN_VALUE

这里循环体从位置16开始,一直持续到25.循环体的字节码是相同的;唯一的区别是用于将STORE_NAME的返回值存储到foo()的额外操作码list,以及用于从LOAD_NAME检索值的额外list

相关问题