Why is a list comprehension so much faster than appending to a list?
本问题已经有最佳答案,请猛点这里访问。
我在想,为什么列表理解要比添加到列表中快得多。我认为差异只是表达性的,但不是。
1 2 3 4 5 6 7 8 9 | >>> import timeit >>> timeit.timeit(stmt='''\ t = [] for i in range(10000): t.append(i)''', number=10000) 9.467898777974142 >>> timeit.timeit(stmt='t= [i for i in range(10000)]', number=10000) 4.1138417314859 |
列表理解速度快50%。为什么?
列表理解基本上只是常规
请考虑以下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # Python-3.6 In [1]: import dis In [2]: def f1(): ...: l = [] ...: for i in range(5): ...: l.append(i) ...: In [3]: def f2(): ...: [i for i in range(5)] ...: In [4]: dis.dis(f1) 2 0 BUILD_LIST 0 3 STORE_FAST 0 (l) 3 6 SETUP_LOOP 33 (to 42) 9 LOAD_GLOBAL 0 (range) 12 LOAD_CONST 1 (5) 15 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 18 GET_ITER >> 19 FOR_ITER 19 (to 41) 22 STORE_FAST 1 (i) 4 25 LOAD_FAST 0 (l) 28 LOAD_ATTR 1 (append) 31 LOAD_FAST 1 (i) 34 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 37 POP_TOP 38 JUMP_ABSOLUTE 19 >> 41 POP_BLOCK >> 42 LOAD_CONST 0 (None) 45 RETURN_VALUE In [5]: dis.dis(f2) 2 0 LOAD_CONST 1 (<code object <listcomp> at 0x7fe48b2265d0, file"<ipython-input-3-9bc091d521d5>", line 2>) 3 LOAD_CONST 2 ('f2.<locals>.<listcomp>') 6 MAKE_FUNCTION 0 9 LOAD_GLOBAL 0 (range) 12 LOAD_CONST 3 (5) 15 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 18 GET_ITER 19 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 22 POP_TOP 23 LOAD_CONST 0 (None) 26 RETURN_VALUE |
您可以看到,在偏移量22处,我们在第一个函数中有一个
即使考虑到查找和加载
1 2 3 4 5 6 7 8 9 10 11 12 | # Slow timeit.timeit(stmt=''' for i in range(10000): t.append(i)''', setup='t=[]', number=10000) # Faster timeit.timeit(stmt=''' for i in range(10000): l(i)''', setup='t=[]; l=t.append', number=10000) # Faster still timeit.timeit(stmt='t = [i for i in range(10000)]', number=10000) |
号
引用本文,这是因为