This question already has answers here:
How does a for loop evaluate its argument
                                
                                    (3个答案)
                                
                        
                                3年前关闭。
            
                    
在循环的每个重复中都调用foo()吗?

for num in foo():
    # Do something


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

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

最佳答案

否。在两个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_NAMEfoo()的返回值存储到list中,以及额外的LOAD_NAMElist检索值。

关于python - Python:“for foo()中的num”循环中的函数foo()多次调用了吗? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36594326/

10-12 18:44