📜  Python|哪个初始化列表更快?

📅  最后修改于: 2022-05-13 01:55:42.308000             🧑  作者: Mango

Python|哪个初始化列表更快?

Python是一种非常灵活的语言,其中可以通过多种方式执行单个任务,例如可以通过多种方式执行初始化列表。然而,这些看似相似的方法却有着细微的差别。 Python因其简单性和可读性而广受欢迎,但与 C++ 或Java相比,它同样因速度慢而臭名昭著。众所周知,'for' 循环很慢,而 map() 和 filter() 等方法速度更快,因为它们是用 C 编写的。了解初始化列表的更好更快的方法可能会让您在竞争中稍有优势编程。

以下是在Python中初始化列表的一些方法(我们创建大小为 1000 的列表并用零初始化)。

使用 for 循环和 append()
我们创建一个空列表并使用 append() 方法运行 for 循环 n 次,以将元素添加到列表中。

arr = []
for i in range(1000):
    arr.append(0)

使用带有计数器变量的 while 循环
这与上述方法类似。但是我们使用 while 循环代替。

arr = []
i = 0
while(i<1000):
    arr.append(0)

使用列表推导
它由方括号组成,其中包含一个表达式,后跟一个 for 子句,再后跟一个可选的 if 子句。表达式可以是我们想要放在列表中的任何类型的对象。由于我们用零初始化列表,我们的表达式将只是 0。

arr = [0 for i in range(1000)]

使用 *运算符
*运算符可用作 [object]*n,其中 n 是数组中元素的数量。

arr = [0]*1000

让我们看看他们每个人所花费的时间。我们将计算每种方法初始化一个包含 10000 个元素的数组超过 500 次所花费的平均时间。

# import time module to calculate times
import time
  
# initialize lists to save the times
forLoopTime = []
whileLoopTime = []
listComprehensionTime = []
starOperatorTime = []
  
# repeat the process for 500 times
# and calculate average of times taken.
for k in range(500): 
  
    # start time
    start = time.time()
    # declare empty list
    a = []
    # run a for loop for 10000 times
    for i in range(10000):
        a.append(0)
    # stop time
    stop = time.time()
    forLoopTime.append(stop-start)
  
    # start time
    start = time.time()
    # declare an empty list
    a = []
    i = 0
    # run a for loop 10000 times
    while(i<10000):
        a.append(0)
        i+= 1
    stop = time.time()
    whileLoopTime.append(stop-start)
  
    start = time.time()
    # list comprehension to initialize list
    a = [0 for i in range(10000)] 
    stop = time.time()
    listComprehensionTime.append(stop-start)
  
  
    start = time.time()
    # using the * operator
    a = [0]*10000 
    stop = time.time()
    starOperatorTime.append(stop-start)
  
  
  
print("Average time taken by for loop: " + str(sum(forLoopTime)/100))
print("Average time taken by while loop: " + str(sum(whileLoopTime)/100))
print("Average time taken by list comprehensions: " + str(sum(listComprehensionTime)/100))
print("Average time taken by * operator: " + str(sum(starOperatorTime)/100))    

输出

Average time taken by for loop: 0.012432687282562256
Average time taken by while loop: 0.017907898426055908
Average time taken by list comprehensions: 0.0034629487991333007
Average time taken by * operator: 0.0001951146125793457

注意:时间将根据执行此代码的平台而有所不同。这些时间只是为了研究这些初始化方法的相对性能。

  • 可以看出,for 和 while 循环花费的时间几乎相同,而 for 循环具有轻微的优势。
  • 列表推导式的性能比 for 和 while 循环要好得多,前者的速度大约快 3-5 倍。当我们尝试创建一个从 1 到 1000 的数字列表时,可以看到这种差异的另一个示例。使用列表推导比使用 append() 好得多。
    a = [i for  i in range(1, 1001)]
  • 使用 *运算符比其他方法快得多,这是您应该初始化列表的方式

然而,使用 *运算符的一个缺点是在声明 2d 数组时。使用此运算符将创建浅表,即仅创建一个列表对象,所有索引都将引用该对象。这可能会造成不必要的并发症。因此,使用列表推导是创建 2d 列表的更安全的方法。

Using * operator would create shallow lists
arr = [[0]*no_of_cols]*no_of_rows

Using list comprehensions is better for 2d arrays
arr = [[0 for i in range(no_of_cols)] for j in range(no_of_rows)]