我正在阅读关于
loops的Python维基,它说
List comprehensions were added to Python in version 2.0 as well. They provide a syntactically more compact and more efficient way of writing the above for loop:
但是,我发现当我测试这个时,我会得到一些意想不到的结果.
In [22]: def while_loop(n):
...: i = 0
...: while i < n:
...: i+=1
...:
In [23]: def while_loop_2(n):
...: while n > 0:
...: n-=1
...:
In [24]: def for_loop(n):
...: for _ in range(n):
...: pass
...:
In [30]: %timeit(for_loop(1000000))
10 loops, best of 3: 23.9 ms per loop
In [31]: %timeit(while_loop(1000000))
10 loops, best of 3: 37.1 ms per loop
In [32]: %timeit(while_loop_2(1000000))
10 loops, best of 3: 38 ms per loop
In [33]: %timeit([1 for _ in range(1000000)])
10 loops, best of 3: 43.2 ms per loop
这引出了一些问题:
>为什么for循环比列表理解快得多? (它似乎快了近两倍)
>为什么while_loop_2比while_loop慢?为什么递增与递减计数器的差异会产生速度上的差异?我的天真使我相信更少的代码行=更快 – 显然情况并非如此
编辑:
这是在Python 2.7中完成的.在3.6中,while_loop_2实际上比while_loop快.所以新问题:
> Python 2.7和3.x之间的while循环有什么区别?
最佳答案 作为序言,你应该意识到你的“比较”应该被孤立地分析(而不是相互比较),因为
> for循环是一个固定的迭代器,它的身体内部什么都不做
> while循环在它们的身体中执行递减/递增,并且
>列表理解不仅仅是一个for循环,并且据说,我会回答问题#1.
#1,因为for循环迭代.列表推导迭代,并在内存中创建一个列表.当然,这有助于节省总时间.仅此一点就足以说服你,但如果不是,请查看反汇编的字节代码,看看每个人在做什么.您可以使用dis模块执行此操作.我实际上用dis来回答你的第三个问题.
#2,至于这个,我无法在python3.6上重现.
%%timeit
i = 0; n = 100000
while i < n: i += 1
11.5 ms ± 65.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
n = 100000
while n > 0: n -= 1
10.8 ms ± 380 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
通常,基于递减的循环应该更快一些,因为与0(n> 0)的比较通常比与非零值(i
import dis
python3.6
06003
python2.7
06004
请注意,生成的字节码存在巨大差异.不同之处在于.