PerryDaPlatypus
PerryDaPlatypus

Reputation: 773

Python pop() vs pop(0)

So the following is confusing me.

#!/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

Results

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

Perhaps, I'm fundamentally misunderstanding how pop is implemented. But my understanding is that it removes the item at the given index in the list, and returns it. If no index is specified, it defaults to the last item. So it would seem that in the first loop it should remove 3 items from the left of the list, and in the second loop it should remove 3 items from the end of the list.

Upvotes: 22

Views: 55384

Answers (4)

David Aderibigbe
David Aderibigbe

Reputation: 11

When you use the 'for item in ITEMS:' command in python; you're still iterating by index, item is still implicitly set as item = ITEMS[index]. each pop(0) shifts the items to the left, and the next item is referenced as item = ITEMS[index++], so, the third zero in test1 is never processed by the loop.

Upvotes: 1

sundar nataraj
sundar nataraj

Reputation: 8692

since in list or Stack works in last in first out[LIFO] so pop() is used it removes last element in your list

where as pop(0) means it removes the element in the index that is first element of the list

as per the Docs

list.pop([i]):

Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. (The square brackets around the i in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.)

Upvotes: 10

nneonneo
nneonneo

Reputation: 179392

The first test isn't surprising; three elements are removed off the end.

The second test is a bit surprising. Only two elements are removed. Why?

List iteration in Python essentially consists of an incrementing index into the list. When you delete an element you shift all the elements on the right over. This may cause the index to point to a different element.

Illustratively:

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]
   ^

and from now on no zeros are encountered, so no more elements are deleted.


To avoid confusion in the future, try not to modify lists while you're iterating over them. While Python won't complain (unlike dictionaries, which cannot be modified during iteration), it will result in weird and usually counterintuitive situations like this one.

Upvotes: 31

sth
sth

Reputation: 229593

You are modifying the lists while you are iterating over them, causing confusion. If you look at the first element, remove it and then continue with looking at the second element, then you missed one element.

The element that was originally in second place was never inspected, because it "changed places" during iteration.

Upvotes: 6

Related Questions