如何高效地移除列表中的最后一个元素?

10
使用列表[-1, 0, 43, 128, 32],有几种方法可以删除最后一个元素。
  • list.pop()
  • list = list[:-1](不推荐使用?)
  • del list[-1]
  • 可能还有其他方法...
它们都会返回[-1, 0, 43, 128],但哪个计算量最小并且是否有差别?我知道有一些模块(例如timeit),可以用来测试这个问题。但是我担心会有无法控制的变量,而且我的非专业知识肯定会影响结果。此外,对于字符串、浮点数或布尔值之类的数据类型,最佳选项是否有所不同?多维列表呢?
我不太确定如何控制和测试这些变量,所以我想在这里询问是否有通用优先级。

不是Difference between del, remove and pop on lists的重复问题

该问题解释了删除方法之间的区别,但没有涉及到切片。它也没有涉及速度问题。被接受的答案提到了效率,我可以看到它是解决方案的一部分,但是我不知道如何与切片相关。

@Mike 那个链接是说 pop 操作已经被修复了,但是切片操作的时间复杂度会随着列表长度的增加而增加。至于平均测试它们的性能,如果我有时间的话,可能会在一两个小时内完成。 - user8866053
timeit 模块是专门设计用于进行此类测试的。你试过了吗?特别是在 IPython 控制台中使用 %timeit 命令,非常容易操作。 - Rory Daulton
@Mike,啊,第二个答案。我现在看到了!谢谢! - user8866053
1个回答

8
根据Python wiki中提到的,时间复杂度如下:
  • 弹出最后一个元素O(1)
  • 删除项O(n)
  • 设置切片O(k+n)

实验研究

import time

all_t = 0.
for i in range(1000):
    list_ = [i for i in range(100000)]
    start_ = time.time()
    list_.pop()
    all_t += time.time() - start_
print("Average Time for POP is {}".format(all_t/1000.))

all_t = 0.
for i in range(1000):
    list_ = [i for i in range(100000)]
    start_ = time.time()
    del list_[-1]
    all_t += time.time() - start_
print("Average Time for DEL is {}".format(all_t/1000.))

all_t = 0.
for i in range(1000):
    list_ = [i for i in range(100000)]
    start_ = time.time()
    list_ = list_[:-1]
    all_t += time.time() - start_
print("Average Time for SLICE is {}".format(all_t/1000.))

结果

Average Time for POP is 7.793903350830078e-07
Average Time for DEL is 9.80854034423828e-07
Average Time for SLICE is 0.0006206443309783935

概述

pop() 在不指定索引时速度最快。


2
@HaleemurAli,第一种和第二种方法末尾都有“e-07”,这是怎么回事?我去掉了“if语句”后重复了一遍,以避免任何混淆,以防万一“if语句”会导致任何滞后。然而,结果仍然相同。 - Yahya
“del” 通常情况下的时间复杂度为 O(n), 就像带有显式参数 的 “pop” 一样。根据您的实验结果,“del list[-1]” 的速度不会比 “pop()” 慢很多。 - chepner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接