Понимание списка и передача выражения генератора в список
Существует мнение, что понимание списка является синтаксическим сахаром для передачи выражения генератора в 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
Может кто-то уточнить, что именно здесь происходит?