Difference between del, remove, and pop on lists
The effects of the three different methods to remove an element from a list:
remove
removes the first matching value, not a specific index:
>>> a = [0, 2, 3, 2]
>>> a.remove(2)
>>> a
[0, 3, 2]
del
removes the item at a specific index:
>>> a = [9, 8, 7, 6]
>>> del a[1]
>>> a
[9, 7, 6]
and pop
removes the item at a specific index and returns it.
>>> a = [4, 3, 5]
>>> a.pop(1)
3
>>> a
[4, 5]
Their error modes are different too:
>>> a = [4, 5, 6]
>>> a.remove(7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
>>> del a[7]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>> a.pop(7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop index out of range
the difference between pop() and del keyword
You're correct that, for single list elements, the value or lack thereof is the only difference. However, del
has a broader range of applicability: it can remove slices from a list, and it can also destroy variables, attributes, and mapping entries.
Difference between pop, del, and remove in runtime
Going By one of the comments in this post to the accepted answer it says that pop gets translated into a function call while del acts as a primitive that's why pop is slower as compared to del
Is del or pop preferred when removing elements from dicts
I would not worry about the performance differences unless you have specific reason to believe that they are causing meaningful slowdowns in your program, which is unlikely.
The real reason you might choose to use del
vs pop
is because they have different behaviors. pop
returns the value for the popped key, so you would use pop
if you want to do something with that value at the same time as you remove it. If you don't need to do anything with the value, but just want to remove the item, use del
.
Difference between list.pop() and list = list[:-1]
Yes. pop
is O(1) and mutates the original list, while slice is O(n) and creates a copy of the list. Less formally, the pop
method is an operation on the element at the end of the list and is defined in CPython as a call to list_resize(self, Py_SIZE(self) - 1);
. This doesn't traverse the entire structure.
On the other hand, list_slice
allocates a new list and loops over the entries in the old list ranging from the beginning to the end - 1, copying references to each item to the new list.
If what you're trying to do is remove the last element of the list, use pop
or del a[-1]
.
What is the difference between pop() and pop()[0]?
I'm assuming, based on your phrasing, that self.items
is a list
. The pop
method for lists, as you've pointed out, can be used to remove and return an element of the list at a specified index. If you omit the index, then the last item is removed and returned.
Either way, pop
returns the item that was removed. If you put [0]
after the call to pop
, you'll get the first item of the item that was popped. So, if self.items
is [[1, 2, 3], [4, 5, 6]]
, then self.items.pop()
would be [4, 5, 6]
and therefore self.items.pop()[0]
would be 4
.
Difference between pop and [:-1] for lists, and different behaviour for s[:-1] when s is a string or a list
You're correct it has to do with references and list
slicing.
partial.pop()
modifies the list
bound to partial
in-place.
partial = partial[:-1]
makes a shallow copy of the list
, and rebinds partial
to the new list
.
This is an important distinction because rebinding doesn't change any other aliases referring to the original list
, which includes the caller's binding to that same list
. To make the two behave almost equivalently (pop
is much more efficient, and unlike slicing, will error on an empty list
) you can use:
partial[:] = partial[:-1]
which reassigns the contents of the original list
to the contents of the shallow copy, or, with equivalent (possibly slightly better) performance than pop
:
# Errors on empty list like pop
del partial[-1]
# Or to silently do nothing when applied to an empty list:
del partial[-1:]
which directly deletes the element without returning it.
None of these can be made to work with str
, because str
is immutable; it's impossible to modify aliases of the same str
in place, you can only make new str
and rebind a given name, which doesn't work for this case. An easy solution is to make your code that works with str
convert it to either a list
, or, if only ASCII/latin-1 characters occur in the str
to encode it to bytes
and then convert to bytearray
, which is mutable and might allow you to use your code that expects mutable sequences more directly.
Related Topics
Why Is "1000000000000000 in Range(1000000000000001)" So Fast in Python 3
What Is the Python Keyword "With" Used For
Pandas Get Rows Which Are Not in Other Dataframe
How to Set Environment Variables in Python
How to Update a Plot in Matplotlib
Difference Between Numpy.Array Shape (R, 1) and (R,)
How to Apply a Function to Two Columns of Pandas Dataframe
Is There a Portable Way to Get the Current Username in Python
Use Numpy Array in Shared Memory For Multiprocessing
Append Existing Excel Sheet With New Dataframe Using Python Pandas
Why Are Python'S 'Private' Methods Not Actually Private
How to Sort a List of Strings Numerically
Lambda in For Loop Only Takes Last Value
Updating Gui Elements in Multithreaded Pyqt
Using Numpy to Build an Array of All Combinations of Two Arrays