【发布时间】:2020-11-15 16:40:55
【问题描述】:
我想知道切片是否会创建列表的副本,以及我们是否在切片上使用 del。那么它不会创建一个副本,即首先从列表中为给定切片创建一个新对象,然后再删除它吗?
所以如果一个程序是真正就地的,那么我们就不能使用切片。
# suppose if I use something like this:
a = [1,2,3,4,5,6,7,8,9,0]
del a[5:]
那么,这个del [a:] 不会在给定的切片a[5:] 中创建a 的副本然后删除它吗?
是这样,因为我们在这里使用切片,所以它不会是就地操作。
但是
a = [1,2,3,4,5,6,7,8,9,0]
for i in range(5,len(a),-1):
del a[i]
这个操作是就地的,因为我们没有使用切片。
所以这应该更快吧?因为我们不必经历创建新切片和直接删除对象的痛苦。
但我查了一下,结果恰恰相反:
%%timeit
a = [x for x in range(1000)]
del a[500:]
> 45.8 µs ± 3.05 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
a = [x for x in range(1000)]
for i in range(999,499,-1):
del a[i]
> 92.9 µs ± 3.24 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
现在,如果我们假设del a[500:] 先创建一个切片然后删除,那么它就不是真正的就地,并且对同一任务使用for 循环是否就地?
但是为什么循环需要更多时间来完成任务呢?
另外,如果以防万一,我假设它们都在原地,del a[500:] 不会在该索引处创建a 的切片副本,del 直接进入索引 500 并递归删除元素,那么这个语句中的 a[500:] 到底是什么?只是告诉del应该从哪里删除?
如果是,那它不是切片吗?
我参考了一些链接,例如下面的链接来找到答案,但从专门针对 in-place 操作的任何解释中,我都不是很清楚。
【问题讨论】:
标签: python list memory slice del