pythonmapiter_python`for i in iter`vs`while True;i=next(iter)`

第三个选项与前两个选项完全相同。第三个示例创建一个列表,每个列表对应print(i)的返回值,正好是None,因此不是一个非常有趣的列表。在

前两个在语义上是相似的。这里有一个小的技术上的区别;如果my_iter不是迭代器(即有一个__next__()方法),那么while循环就不起作用;例如,如果它是list。for循环适用于除迭代器之外的所有iterables(有一个__iter__()方法)。在

因此,正确的版本是:my_iter = iter(my_iterable)

try:

while True:

i = next(my_iter)

print(i)

except StopIteration:

pass

现在,除了可读性原因之外,事实上是一个您应该选择for循环的技术原因;对于在紧凑的内部循环中执行的字节码数量,您要付出一定的代价(无论如何,在CPython中)。让我们比较一下:

^{pr2}$

内环中调用的7字节码vs:In [55]: def whileloop(my_iterable):

....: my_iter = iter(my_iterable)

....: try:

....: while True:

....: i = next(my_iter)

....: print(i)

....: except StopIteration:

....: pass

....:

In [56]: dis.dis(whileloop)

2 0 LOAD_GLOBAL 0 (iter)

3 LOAD_FAST 0 (my_iterable)

6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

9 STORE_FAST 1 (my_iter)

3 12 SETUP_EXCEPT 32 (to 47)

4 15 SETUP_LOOP 25 (to 43)

5 >> 18 LOAD_GLOBAL 1 (next)

21 LOAD_FAST 1 (my_iter)

24 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

27 STORE_FAST 2 (i)

6 30 LOAD_GLOBAL 2 (print)

33 LOAD_FAST 2 (i)

36 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

39 POP_TOP

40 JUMP_ABSOLUTE 18

>> 43 POP_BLOCK

44 JUMP_FORWARD 18 (to 65)

7 >> 47 DUP_TOP

48 LOAD_GLOBAL 3 (StopIteration)

51 COMPARE_OP 10 (exception match)

54 POP_JUMP_IF_FALSE 64

57 POP_TOP

58 POP_TOP

59 POP_TOP

8 60 POP_EXCEPT

61 JUMP_FORWARD 1 (to 65)

>> 64 END_FINALLY

>> 65 LOAD_CONST 0 (None)

68 RETURN_VALUE

内环中有9个字节码。在

不过,我们实际上可以做得更好。在In [58]: from collections import deque

In [59]: def deqloop(my_iter):

....: deque(map(print, my_iter), 0)

....:

In [61]: dis.dis(deqloop)

2 0 LOAD_GLOBAL 0 (deque)

3 LOAD_GLOBAL 1 (map)

6 LOAD_GLOBAL 2 (print)

9 LOAD_FAST 0 (my_iter)

12 CALL_FUNCTION 2 (2 positional, 0 keyword pair)

15 LOAD_CONST 1 (0)

18 CALL_FUNCTION 2 (2 positional, 0 keyword pair)

21 POP_TOP

22 LOAD_CONST 0 (None)

25 RETURN_VALUE

所有的事情都发生在C中,collections.deque,map和{}都是内置函数。(对于cpython)所以在本例中,没有为循环执行字节码。只有当迭代步骤是一个c函数时,这才是一个有用的优化(例如print)。否则,python函数调用的开销大于JUMP_ABSOLUTE开销。在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值