This question already has answers here:
How does a for loop evaluate its argument
(3个答案)
3年前关闭。
在循环的每个重复中都调用foo()吗?
如果这样效率低下,那么这段代码会更好吗?
在上面的字节码中,循环主体从
在这里,循环体从位置16开始,一直到25。循环体的字节码是相同的。唯一的区别是额外的操作码
(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_NAME
将foo()
的返回值存储到list
中,以及额外的LOAD_NAME
从list
检索值。关于python - Python:“for foo()中的num”循环中的函数foo()多次调用了吗? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36594326/
10-12 18:44