为什么在Python中快速使用[e]*n(用于创建重复n次的单项列表)?

yan*_*ng5 1 python list

跟进: 在Python中创建单项重复n次的列表

python -m timeit '[0.5]*100000'
1000 loops, best of 3: 382 usec per loop

python -m timeit '[0.5 for i in range(100000)]'
100 loops, best of 3: 3.07 msec per loop
Run Code Online (Sandbox Code Playgroud)

显然,由于range(),第二个较慢.我不知道为什么[e]*n如此之快(或者它是如何在Python内部实现的).

unu*_*tbu 6

dis.dis允许您查看Python在评估每个表达式时执行的操作:

In [57]: dis.dis(lambda: [0.5]*100000)
  1           0 LOAD_CONST               1 (0.5)
              3 BUILD_LIST               1
              6 LOAD_CONST               2 (100000)
              9 BINARY_MULTIPLY     
             10 RETURN_VALUE        

In [58]: dis.dis(lambda: [0.5 for i in range(100000)])
  1           0 BUILD_LIST               0
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_CONST               1 (100000)
              9 CALL_FUNCTION            1
             12 GET_ITER            
        >>   13 FOR_ITER                12 (to 28)
             16 STORE_FAST               0 (i)
             19 LOAD_CONST               2 (0.5)
             22 LIST_APPEND              2
             25 JUMP_ABSOLUTE           13
        >>   28 RETURN_VALUE        
Run Code Online (Sandbox Code Playgroud)

列表推导执行循环,0.5每次加载常量,并将其附加到结果列表.

表达式[0.5]*100000只需要一个BINARY_MULTIPLY.


另请注意,[obj]*N制作一个长度列表N,N参考完全相同obj.

列表推导[expr for i in range(N)] 评估 expr N时间 - 即使expr每次评估到相同的值.