>>> a = [1,2,3]
>>> a.pop()
3
>>> a
[1, 2]
>>> a = [1,2,3]
>>> a = a[:-1]
>>> a
[1, 2]
>>>
以上方法从列表中删除最后一个元素之间有什么区别吗?
pop
的时间复杂度为 O(1),并且会改变原始列表,而切片的时间复杂度为 O(n),并且会创建一个列表的副本。更不正式地说,pop
方法是对列表末尾元素的操作,并在 CPython 中定义为调用 list_resize(self, Py_SIZE(self) - 1);
。 这不需要遍历整个结构。list_slice
会分配一个新的列表,并循环遍历旧列表中的条目,范围从开头到结尾-1,将每个项目的引用复制到新列表中。pop
或 del a[-1]
。pop
可以接受一个索引参数,例如 pop(0)
,在这种情况下,它仍然是 O(1)
吗? - LiuXiMinpop
在栈数据结构的“顶部”或“后部/右侧”传统上是O(1)操作。Python中的列表给pop
增加了一个额外参数以使其能够在中间工作,但是列表中的其他元素需要向前移动以填补空缺,这是O(n)。查看源代码以获取完整的故事。有一个条件语句在pop()
和pop(n)
之间进行切换——后者调用list_ass_slice(self, index, index+1, (PyObject *)NULL);
对列表执行向前移动操作。如果您经常使用pop(0)
,请查看collections.deque
。 - ggorlenlist
的最后一个元素,那么使用del mylist[-1]
就可以了。当你想要删除list
的最后一个元素并保留该值(pop
返回该值)时,你会使用pop
。del mylist[-1]
与pop
具有相同的大O行为,并且它直接支持语法/字节码,这通常比函数调用更快(尽管现代版本的CPython通过加速简单方法调用来缩小差距)。 - ShadowRangerpop
不改变列表的标识符,只是从列表中弹出一个项目。
[:-1]
是切片操作,它从旧列表创建一个新列表。
>>> a = [1,2,3]
print(id(a))
>>> a.pop()
3
print(id(a))
>>> a
[1, 2]
>>> a = [1,2,3]
>>> a = a[:-1]
>>> a
print(id(a))
[1, 2]
>>>
id输出(数字无关紧要,重点是相同或不同):
4470627464
4470627464
4474450952
pop
会改变a
所引用的列表,而切片操作会将a
更新为引用新列表,因此当其他变量引用同一列表时,主要区别就出现了。 - Hammspop 方法返回从列表中删除的最后一项。 例如:
a = [1,2,3,4]
b = a.pop()
print(b) # 4
在函数使用中存在一个基本差异。使用[:-1]
不会改变原始列表,但是pop()
可以。
a = [1,2,3]
b = [1,2,3]
def functionb(list):
list = list[:-1]
return list
def withpop(list):
return list.pop()
functionb(b)
withpop(a)
print b
print a
将打印:
[1, 2, 3]
[1, 2]
pop()
比 [:-1]
更快,因为当你使用 [:-1]
时,你必须覆盖列表。假设你有成千上万个值在索引中,所以它会比 pop()
慢。是的,有区别。 当您使用a.pop()时,您也会从列表中删除 当您使用a[:-1]对象列表不会改变 检查len(a)
>>> a = [1,2,3]
>>> a
[1, 2, 3]
>>> a[:-1]
[1, 2]
>>> len(a[:-1])
2
>>> a.pop()
3
>>> a
[1, 2]
>>> len(a)
2
>>>
从外观上看,你所展示的两种方式没有区别。 pop
指令使解释器更容易优化指令,因为它只需将列表的长度属性减少一个。而 -1
赋值将构造一个新列表,将其分配给 a
,然后将旧列表留给垃圾回收。
在别名方面有很大的区别:如果你将其他东西分配给该列表,使用 pop
将会产生副作用。例如:
>>> a = [1, 2, 3, 4]
>>> b = a
>>> b
[1, 2, 3, 4]
>>> a.pop()
4
>>> b
[1, 2, 3]
>>> a = a[:-1]
>>> b
[1, 2, 3]
>>> a
[1, 2]
a = a[:-1]
更改为 a[:] = a[:-1]
;而不是将 a
重新绑定到新的 list
,将“空”切片赋值将用切片的结果替换原始 list
的 内容。 - ShadowRanger
pop
在常数时间内就地修改了被a
引用的列表,而使用切片则创建了一个新列表并将其分配给a
,并在线性时间内工作。 - juanpa.arrivillaga