Difference between pop and remove
python - Issue with reversing list using list.pop() - Stack Overflow
How to reverse order to pop out Python 3.6.4 - Stack Overflow
python - How do I remove the first item from a list? - Stack Overflow
Videos
Can someone explain me what the difference between pop and remove is that makes sense? Why would you use pop over remove or vice versa?
Thanks!
How about a simple reversal of string.
>>> x = 'abcd'
>>> x[::-1]
'dcba'
>>>
On your code:
Never mutate the list on which you are iterating with. It can cause subtle errors.
>>> strList = [1, 2, 3, 4, 5]
>>> reverseCharList = []
>>> for someChar in strList:
... print strList
... reverseCharList.append(strList.pop())
... print strList
...
[1, 2, 3, 4, 5] <-- Iteration 1
[1, 2, 3, 4]
[1, 2, 3, 4] <-- Iteration 2
[1, 2, 3]
[1, 2, 3] <-- Iteration 3
[1, 2]
See the following. Since you are using iterator (for .. in ..). You can see the iterator details directly and how mutating the list messes up with iterator.
>>> strList = [1, 2, 3, 4, 5]
>>> k = strList.__iter__()
>>> k.next()
1
>>> k.__length_hint__() <--- Still 4 to go
4
>>> strList.pop() <---- You pop an element
5
>>> k.__length_hint__() <----- Now only 3 to go
3
>>>
>>> k.next()
2
>>> k.__length_hint__()
2
for someChar in strList:
reverseCharList.append(strList.pop())
Is essentially the same as:
i = 0
while i < len(strList):
reverseCharList.append(strList.pop())
i += 1
First iteration i is 0, len(strList) is 4, and you pop+append 'd'.
Second iteration i is 1, len(strList) is 3, and you pop+append 'c'.
Third iteration i is 2, len(strList) is 2, so the loop condition fails and you're done.
(This is really done with an iterator on the list, not a local variable 'i'. I've shown it this way for clarity.)
If you want to manipulate the sequence you're iterating over it's generally better to use a while loop. eg:
while strList:
reverseCharList.append(strList.pop())
Although it's generally not a good pattern to use a dictionary as an ordered data type, you can do what you want like this:
my_dictionary.pop(next(iter(my_dictionary.keys())))
.popitem() doesn't take parameters, but .pop() does take a specific key to pop.
Even if dicts happen to be ordered in CPython 3.6+, they're the not right data structure if you need this sort of thing. I'd recommend using a list of 2-tuples instead.
If you don't want to do that, you can, as a hack, find the "first" key, then pop the value:
next_key = next(iter(my_dictionary))
next_value = my_dictionary.pop(next_key)
This may fail on other Python implementations than CPython.
You can find a short collection of useful list functions here.
list.pop(index)
>>> l = ['a', 'b', 'c', 'd']
>>> l.pop(0)
'a'
>>> l
['b', 'c', 'd']
>>>
del list[index]
>>> l = ['a', 'b', 'c', 'd']
>>> del l[0]
>>> l
['b', 'c', 'd']
>>>
These both modify your original list.
Others have suggested using slicing:
- Copies the list
- Can return a subset
Also, if you are performing many pop(0), you should look at collections.deque
from collections import deque
>>> l = deque(['a', 'b', 'c', 'd'])
>>> l.popleft()
'a'
>>> l
deque(['b', 'c', 'd'])
- Provides higher performance popping from left end of the list
Slicing:
x = [0,1,2,3,4]
x = x[1:]
Which would actually return a subset of the original but not modify it.
I've been strugling with a program implementation for some time now, and I just noticed a very wierd behavior of the pop method (pop is in my file, and del, as an alternative, returned the same result). Here is a minimun reproductible example:
words = (5*'Loren ipsun ').split()
print(words,'\n')
for i in range(10):
words.pop(i)
print(words)This is the console output:
['Loren', 'ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun'] ['ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun'] ['ipsun', 'ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun'] ['ipsun', 'ipsun', 'ipsun', 'Loren', 'ipsun', 'Loren', 'ipsun'] ['ipsun', 'ipsun', 'ipsun', 'ipsun', 'Loren', 'ipsun'] ['ipsun', 'ipsun', 'ipsun', 'ipsun', 'ipsun'] Traceback (most recent call last): IndexError: pop index out of range
Could someone explain to me why just Loren words are being erased?
[Edit] Solution:
words = (5*'Loren ipsun ').split()
print(words,'\n')
for i in range(10):
words.pop(0)
print(words)I know there is a list.clear(), I'm just sharing that I didn't expect that using list.pop() and list.remove() specifically could slow down the program that much.
li = list(range(500000))
Creating a list is quick.
So we are going to test out pop/remove specific values. For the purpose of this "benchmark", we are going to remove all elements from the list:
while (li):
li.pop(0)
It took 74.735 seconds to pop all the elements! It's ridiculously long.
I KNOW it would have been much faster if I even had used li.pop() without the index or maybe used filter function, list comprehension with conditional or whatever
But that's what I'm trying to show, how slow it is to remove certain list items specifically using pop and remove methods.
And li.remove(), which always requires a specified value to remove, is even worse than pop!
for num in li:
li.remove(num)This one took me 303.268 seconds to complete. How crazy it is.
I've been having fun with abstract data structures. Implemented linked lists and a queues running on linked lists.
And for the sake of interest, I decided to compare the performance of the queue based on the linked list and the usual python list. And I was surprised. When my linked list Queue dequeued 500.000 elements in 0.5 seconds, while python list Queue was doing it in 75 seconds.