Python pop() 与 pop(0) 的区别
我有点困惑。
#!/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 个回答
当你在Python中使用'for item in ITEMS:
'这个命令时,其实你还是在通过索引来遍历。也就是说,item
实际上是隐含地被设置为item = ITEMS[index]
。每次使用pop(0)
时,列表里的项目会向左移动,这样下一个item就会被当作item = ITEMS[index++]
来引用。所以,在test1中第三个零就永远不会被循环处理到。
你在遍历列表的时候同时修改它们,这样会让人搞混。如果你先看第一个元素,把它删掉,然后继续看第二个元素,那你就会漏掉一个元素。
原本在第二个位置的元素在你遍历的时候就没被检查,因为它的位置在遍历过程中“变了”。
因为列表或栈的工作方式是后进先出,也就是最后放进去的东西最先拿出来,所以使用 pop()
方法可以移除你列表中的最后一个元素。
而 pop(0)
则是指移除列表中第一个元素。
根据文档的说明:
list.pop([i]):
在列表中移除指定位置的项目,并返回它。如果没有指定索引,a.pop() 会移除并返回列表中的最后一个项目。(方法签名中 i 的方括号表示这个参数是可选的,并不是说你需要在那个位置输入方括号。你会在 Python 库参考中经常看到这种表示法。)
第一个测试结果并不让人意外;三个元素被从末尾删除了。
第二个测试结果有点让人意外。只有两个元素被删除。为什么呢?
在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不会报错(和字典不同,字典在遍历时不能被修改),但这样做会导致一些奇怪且通常不符合直觉的情况,就像这个例子一样。