通过使列表等于一个切片来截断列表,还是使用del来截断它?

2024-09-30 22:18:55 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个listTruncList,其中一些元素的数量大于n。如果我想从列表的末尾删除n元素,那么将列表重新定义为自身的一部分保留所需的元素,如TruncList = TruncList[:-n],还是从列表中删除不需要元素的部分,如del TruncList[-n:],是否更快?在

如果我从TruncList中删除第一个n元素,就像TruncList = TruncList[n:]和{}相比,答案会改变吗?在

除了速度,这些方法中的一个比另一个更像Python吗?在

我可以想象,重定义方法可能会比较慢,因为它会遍历TruncList然后重新分配它,而{}会在适当的地方截断列表,但我不确定这两种情况是否都是这样。在

我还假设del是更好的路径,因为它看起来像是函数的自然使用。在


Tags: 方法答案元素列表数量定义地方情况
2条回答

这完全取决于你删除了多少元素。在

在CPython中,list类型使用动态过度分配策略,以避免过于频繁地调整底层C数组的大小。有一个array来保存元素,并且它始终保持稍微过大。在

然后删除(使用del TruncList[-n:]可以实际上是一个自由操作,前提是{}足够小。事实上,在调整大小之前,您可以安全地删除超过分配数组大小的一半。调整大小需要跨所有现有引用复制到新数组。在

使用一个切片是总是创建新的列表对象,需要分配内存并跨所涉及的元素进行复制。这比重新分配数据稍微多一些。在

因此,如果不测量时间性能(使用timeit),我希望del选项比切片更快;在n < len(TruncList) // 2(小于长度的一半)的情况下,很多情况下甚至不需要调整大小,即使这样做,所需的工作量也会稍微减少,因为只需重新创建内部数组。在

你总是要从前面的元素中移除元素。这样一来,差异就不会很明显了,但是创建一个切片仍然会导致分配给一个全新的对象。在

所以我用timeit对这些样本进行了测试:

  ## Make a list of 500 elements and then remove the first 80...
def slice_front():
    "Make the list equal to all but the first eighty elements."
    trunc = 80
    TruncList = range(500)
    TruncList = TruncList[trunc:]

def del_front():
    "Use del to remove the first eighty elements."
    trunc = 80
    TruncList = range(500)
    del TruncList[:trunc]


  ## Make a list of 500 elements and then remove the last 80...
def slice_end():
    "Make the list equal to all but the last eighty elements."
    trunc = 80
    TruncList = range(500)
    TruncList = TruncList[:-trunc]

def del_end():
    "Delete the last eighty elements from the list using del."
    trunc = 80
    TruncList = range(500)
    del TruncList[-trunc:]

…结果是:

^{pr2}$

看起来{}速度更快,而且差距很大。在


编辑

如果我运行相同的示例,但是使用trunc = 2,则结果如下:

^{3}$

del仍然更快。在

这里有一个测试,几乎所有的列表元素都被移除:trunc = 80和{}。。。在

>>> timeit.timeit(slice_front, number = 66666)
0.25171681555993247
>>> timeit.timeit(del_front, number = 66666)
0.2696609454136185
>>> timeit.timeit(slice_end, number = 66666)
0.2635454769274057
>>> timeit.timeit(del_end, number = 66666)
0.294670910710936

在这种情况下,del要比重定义方法慢一些。在

相关问题 更多 >