人们认为列表理解是将生成器表达式传递给list
(1,2)的语法糖。虽然我无法查明内部动态来证明并非如此,但我已经能够证明这两种方法之间存在O(n)差异:
n = 100000
%timeit [i for i in range(n)] # 6.03 ms per loop
%timeit list(i for i in range(n)) # 10 ms per loop
%timeit [i for i in range(n*10)] # 117 ms per loop
%timeit list(i for i in range(n*10)) # 157 ms per loop
%timeit [i for i in range(n*100)] # 1.18 s per loop
%timeit list(i for i in range(n*100)) # 1.66 s per loop
O(n)计算:
Scaling = 1, differential = 4ms
Scaling = 10, differential = 40ms
Scaling = 100, differential = 480ms
我看了dis.dis
的输出。这显示了后者的不同处理顺序,但是我不清楚这些函数调用的引用是什么:
import dis
dis.dis('[i for i in range(n)]')
1 0 LOAD_CONST 0 (<code object <listcomp> at 0x0000000004E82300, file "<dis>", line 1>)
2 LOAD_CONST 1 ('<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_NAME 0 (range)
8 LOAD_NAME 1 (n)
10 CALL_FUNCTION 1
12 GET_ITER
14 CALL_FUNCTION 1
16 RETURN_VALUE
dis.dis('list(i for i in range(n))')
1 0 LOAD_NAME 0 (list)
2 LOAD_CONST 0 (<code object <genexpr> at 0x0000000004EF94B0, file "<dis>", line 1>)
4 LOAD_CONST 1 ('<genexpr>')
6 MAKE_FUNCTION 0
8 LOAD_NAME 1 (range)
10 LOAD_NAME 2 (n)
12 CALL_FUNCTION 1
14 GET_ITER
16 CALL_FUNCTION 1
18 CALL_FUNCTION 1
20 RETURN_VALUE
有人能确切说明这里发生了什么吗?