Python pop() 与 pop(0) 的区别

21 投票
4 回答
48717 浏览
提问于 2025-04-18 09:22

我有点困惑。

#!/usr/bin/python

test = [0, 0, 0, 1, 2, 3, 4, 5, 6]
test1 = [0, 0, 0, 1, 2, 3, 4, 5, 6]

for _dummy in test:
    if(_dummy == 0):
        test.pop()
for _dummy in test1:
    if(_dummy == 0):
        test1.pop(0)

print test
print test1

结果

ubuntu-vm:~/sandbox$ ./test.py 
[0, 0, 0, 1, 2, 3]
[0, 1, 2, 3, 4, 5, 6]

也许我对 pop 这个操作的实现有根本性的误解。但我理解的是,它会移除列表中指定位置的项目,并返回这个项目。如果没有指定位置,它默认移除最后一个项目。所以在第一个循环中,它应该从列表的左边移除 3 个项目,而在第二个循环中,它应该从列表的右边移除 3 个项目。

4 个回答

0

当你在Python中使用'for item in ITEMS:'这个命令时,其实你还是在通过索引来遍历。也就是说,item实际上是隐含地被设置为item = ITEMS[index]。每次使用pop(0)时,列表里的项目会向左移动,这样下一个item就会被当作item = ITEMS[index++]来引用。所以,在test1中第三个零就永远不会被循环处理到。

6

你在遍历列表的时候同时修改它们,这样会让人搞混。如果你先看第一个元素,把它删掉,然后继续看第二个元素,那你就会漏掉一个元素。

原本在第二个位置的元素在你遍历的时候就没被检查,因为它的位置在遍历过程中“变了”。

10

因为列表或栈的工作方式是后进先出,也就是最后放进去的东西最先拿出来,所以使用 pop() 方法可以移除你列表中的最后一个元素。

pop(0) 则是指移除列表中第一个元素。

根据文档的说明:

list.pop([i]):

在列表中移除指定位置的项目,并返回它。如果没有指定索引,a.pop() 会移除并返回列表中的最后一个项目。(方法签名中 i 的方括号表示这个参数是可选的,并不是说你需要在那个位置输入方括号。你会在 Python 库参考中经常看到这种表示法。)

29

第一个测试结果并不让人意外;三个元素被从末尾删除了。

第二个测试结果有点让人意外。只有两个元素被删除。为什么呢?

在Python中,遍历列表其实就是一个不断增加的索引在列表中移动。当你删除一个元素时,右边的所有元素都会往左移动。这可能会导致索引指向一个不同的元素。

举个例子:

start of loop
[0,0,0,1,2,3,4,5,6]
 ^   <-- position of index

delete first element (since current element = 0)
[0,0,1,2,3,4,5,6]
 ^

next iteration
[0,0,1,2,3,4,5,6]
   ^

delete first element (since current element = 0)
[0,1,2,3,4,5,6]
   ^

从现在开始就不会再遇到零了,所以也就不会再删除任何元素。


为了避免将来的困惑,尽量不要在遍历列表的同时修改它们。虽然Python不会报错(和字典不同,字典在遍历时不能被修改),但这样做会导致一些奇怪且通常不符合直觉的情况,就像这个例子一样。

撰写回答