如果我有一个长度为10000个条目的列表,那么:会更快吗
- 制作一个空白列表,然后将其追加
或
- 制作一个包含10000个空白条目的列表,并将每个条目设置为数据
示例代码
# first case
a=[]
for i in range(10000):
a.append(input())
# second case
a= [0]*10000
for i in range(10000):
a[i] = input()
timeit
模块非常适合测试这类东西:
# first case
def test1():
a=[]
for i in range(10000):
a.append(1)
# second case
def test2():
a= [0]*10000
for i in range(10000):
a[i] = 1
#list comprehension
def test3():
a = [1 for _ in range(10000)]
import timeit
n = 10000
print("appending: ",timeit.timeit(test1,number=n))
print("assigning: ",timeit.timeit(test2,number=n))
print("comprehension:",timeit.timeit(test3,number=n))
输出:
appending: 13.14265166100813
assigning: 8.314113713015104
comprehension: 6.283505174011225
按照要求,我用sum(timeit.repeat(..., repeat=7))/7
替换了timeit.timeit(...)
以获得平均时间,得到了以下结果:
appending: 12.813485399578765
assigning: 8.514678678861985
comprehension: 6.271697525575291
这与我最初的结果没有太大的不同。
我想我应该尝试使用CS原理来回答,而不是根据经验来计时,因为仅仅计时并不能告诉你为什么一个更好,或者N
的其他值是否正确。
Python列表实现为数组。这意味着"追加"需要定期调整大小,而空白/重新分配选项是一次分配,然后是10000次O(1)访问时间。因此,在限制范围内(例如,对于10K、100K、1M等),由于第一个选项需要调整大小,我预计第二个选项会更快。
欲了解更多信息,请参阅:Python是如何运行的';s列表已执行?
它们在速度上不相上下。@Tadhg建议的列表理解速度大约是原来的两倍。
以下是计时结果:
first case: 10.3030366897583
second case: 9.829667568206787
list comprehension: 5.473726511001587
这是我使用的源代码:
from time import time
from random import random
# first case
iterations = 10000000
start = time()
a=[]
for i in range(iterations):
a.append(random())
print(time() - start)
# second case
start = time()
a= [0]*iterations
for i in range(iterations):
a[i] = random()
print(time() - start)
start = time()
a = [random() for _ in range(iterations)]
print(time() - start)