1192

Is there any difference between these three methods to remove an element from a list?

a = [1, 2, 3]
a.remove(2)
a               # [1, 3]

a = [1, 2, 3]
del a[1]
a               # [1, 3]

a = [1, 2, 3]
a.pop(1)        # 2
a               # [1, 3]
cottontail
  • 10,268
  • 18
  • 50
  • 51
sachin irukula
  • 12,841
  • 4
  • 19
  • 19
  • 2
    Related post on similar lines for set data structure - [Runtime difference between set.discard and set.remove methods in Python?](https://stackoverflow.com/q/27850073/465053) – RBT Aug 01 '18 at 02:51

15 Answers15

1668

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
mit
  • 11,083
  • 11
  • 50
  • 74
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 7
    I thought `del` was a python 2 syntax holdover like `print`, but it still works in python 3. – jxramos Sep 01 '17 at 20:12
  • 25
    @jxramos: `del` is not a syntax holdover, no. The syntax is unchanged, just like `return` or `if` or `while`. – Martijn Pieters Sep 01 '17 at 20:57
  • 18
    It is worth mentioning that users should be careful when iterating over a list and using these functions on it at the same time as they are iterating. – hamaney Mar 29 '19 at 23:12
  • how about big(O)? – Jeffery Dec 16 '19 at 19:22
  • 1
    @Jeffery: See the [TimeComplexity page on the Python Wiki](https://wiki.python.org/moin/TimeComplexity). But they are all O(k), with *k* the number of items that follow after the index you removed. – Martijn Pieters Dec 16 '19 at 20:40
  • How does remove "match" the first value for complex objects (such as objects of custom class, or list of dict etc.) or even for simple objects for that matter? Is it by the id (address in memory) of the object? – rite2hhh Dec 26 '19 at 20:14
  • 6
    @rite2hhh it tests for equality. Equality tests test for identity first as an optimisation – Martijn Pieters Dec 26 '19 at 20:33
  • @MartijnPieters, your updated/edited comment explains it. Thanks! Perhaps my next question is beyond scope, I'll still ask as I'm curious to know. If the identity test fails, how does the comparison for equality occur? If there's a document I can read, that would be great! – rite2hhh Dec 26 '19 at 20:45
  • 3
    @rite2hhh: value equality is covered in the [expression reference](https://docs.python.org/3/reference/expressions.html#value-comparisons). – Martijn Pieters Dec 26 '19 at 21:20
  • How does .remove() determine matching on classes? – Marat Mkhitaryan Jul 29 '20 at 04:20
  • @Cookie: that's not a clear question, what do you mean by *matching on classes*? The remove method is not that complicated, `listobj.remove(argument)` finds the first element that is *equal* to the argument and removes it from the list. Basically: `for i, value in enumerate(listobj): if value == argument: del listobj[i]; return` (with a `raise ValueError()` if the loop terminates without reaching `return`). – Martijn Pieters Jul 29 '20 at 10:53
272

Use del to remove an element by index, pop() to remove it by index if you need the returned value, and remove() to delete an element by value. The last requires searching the list, and raises ValueError if no such value occurs in the list.

When deleting index i from a list of n elements, the computational complexities of these methods are

del     O(n - i)
pop     O(n - i)
remove  O(n)
jtlz2
  • 7,700
  • 9
  • 64
  • 114
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 3
    Does pop require searching the list – sachin irukula Jul 17 '12 at 10:31
  • 61
    +1 for complexity breakdown. Illustrates how delete and pop are constant when the element is at the end of the list. – Big Sharpie Nov 06 '14 at 05:56
  • 4
    Remember guys... anything index based is one shot O(n-1)... if you have to do a lookup (by value), it will traverse the collection until the element is found. – Pepito Fernandez Oct 14 '17 at 14:13
  • 7
    @PepitoFernandez Look-ups by index in a list are O(1) in Python. (A list in Python is similar to a vector in C++.) – Sven Marnach Oct 14 '17 at 19:28
  • @SvenMarnach I meant to say that. O(1). Thanks for the correction. – Pepito Fernandez Oct 14 '17 at 19:32
  • Is there a performance difference between `del` and `pop`? I would suspect del is faster because it returns nothing? – PlasmaBinturong Nov 29 '19 at 18:00
  • 5
    @PlasmaBinturong You should use what you think is more readable, unless you have data that proves that the performance matters. And if you have, you need to measure what's faster in your specific case. My guess is also that `del` is slightly faster, but for a different reason: the lookup for `__delitem__` on a type implemented in C happens by index rather than by name, whereas `pop` needs to be looked up following the whole descriptor protocol. The execution of the functions themselves should take the same amount of time. Both return a pointer – one to the removed object, the other to `None`. – Sven Marnach Nov 29 '19 at 20:08
127

Since no-one else has mentioned it, note that del (unlike pop) allows the removal of a range of indexes because of list slicing:

>>> lst = [3, 2, 2, 1]
>>> del lst[1:]
>>> lst
[3]

This also allows avoidance of an IndexError if the index is not in the list:

>>> lst = [3, 2, 2, 1]
>>> del lst[10:]
>>> lst
[3, 2, 2, 1]
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
71

Already answered quite well by others. This one from my end :)

remove vs pop vs del

Evidently, pop is the only one which returns the value, and remove is the only one which searches the object, while del limits itself to a simple deletion.

Community
  • 1
  • 1
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • 5
    Thnx! One note: in python, due to the way the lists are implemented(there practically arrays...!), "Advance till that node position" is O(1) – ntg Nov 28 '18 at 11:14
31

Many good explanations are here but I will try my best to simplify more.

Among all these methods, remove & pop are postfix while delete is prefix.

remove(): Is used to remove first occurrence of element.
remove(n) => first occurrence of n in the list.

>>> a = [0, 2, 3, 2, 1, 4, 6, 5, 7]
>>> a.remove(2)   # where i = 2
>>> a
[0, 3, 2, 1, 4, 6, 5, 7]

pop(): Is used to remove element ...

  • if no index is specified:
    pop() => from end of list
>>> a.pop()
>>> a
[0, 3, 2, 1, 4, 6, 5]
  • if an index is specified:
    pop(index) => of index
>>> a.pop(2)
>>> a
[0, 3, 1, 4, 6, 5]

WARNING: Dangerous Method Ahead

del(): It's a prefix method.

Keep an eye on two different syntaxes for same method: with [] and without. It possesses power to:

  • Delete index
    del a[index] => used to delete by index and its associated value just like pop.
>>> del a[1]
>>> a
[0, 1, 4, 6, 5]
  • Delete values in range [index_1:index_N]:
    del a[0:3] => multiple values in range.
>>> del a[0:3]
>>> a
[6, 5]
  • Last but not least, to delete whole list in one shot.
    del (a) => as said above.
>>> del (a)
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

Hope this clarifies the confusion.

NerdOnTour
  • 634
  • 4
  • 15
Mayur Patil
  • 952
  • 1
  • 10
  • 18
24

pop

Takes index (when given, else take last), removes value at that index, and returns value

remove

Takes value, removes first occurrence, and returns nothing

delete

Takes index, removes value at that index, and returns nothing

AcK
  • 2,063
  • 2
  • 20
  • 27
Bahubali Patil
  • 1,127
  • 1
  • 16
  • 23
3

Any operation/function on different data structures is defined for particular actions. Here in your case i.e. removing an element, delete, Pop and remove. (If you consider sets, Add another operation - discard) Other confusing case is while adding. Insert/Append. For Demonstration, Let us Implement deque. deque is a hybrid linear data structure, where you can add elements / remove elements from both ends.(Rear and front Ends)

class Deque(object):

  def __init__(self):

    self.items=[]

  def addFront(self,item):

    return self.items.insert(0,item)
  def addRear(self,item):

    return self.items.append(item)
  def deleteFront(self):

    return self.items.pop(0)
  def deleteRear(self):
    return self.items.pop()
  def returnAll(self):

    return self.items[:]

In here, see the operations:

def deleteFront(self):

    return self.items.pop(0)
def deleteRear(self):
    return self.items.pop()

Operations have to return something. So, pop - With and without an index. If I don't want to return the value: del self.items[0]

Delete by value not Index:

  • remove :

    list_ez=[1,2,3,4,5,6,7,8]
    for i in list_ez:
        if i%2==0:
            list_ez.remove(i)
    print list_ez
    

Returns [1,3,5,7]

let us consider the case of sets.

set_ez=set_ez=set(range(10))

set_ez.remove(11)

# Gives Key Value Error. 
##KeyError: 11

set_ez.discard(11)

# Does Not return any errors.
phanindravarma
  • 1,287
  • 2
  • 9
  • 8
3

Here is a detailed answer.

del can be used for any class object whereas pop and remove and bounded to specific classes.

For del

Here are some examples

>>> a = 5
>>> b = "this is string"
>>> c = 1.432
>>> d = myClass()

>>> del c
>>> del a, b, d   # we can use comma separated objects

We can override __del__ method in user-created classes.

Specific uses with list

>>> a = [1, 4, 2, 4, 12, 3, 0]
>>> del a[4]
>>> a
[1, 4, 2, 4, 3, 0]

>>> del a[1: 3]   # we can also use slicing for deleting range of indices
>>> a
[1, 4, 3, 0]

For pop

pop takes the index as a parameter and removes the element at that index

Unlike del, pop when called on list object returns the value at that index

>>> a = [1, 5, 3, 4, 7, 8]
>>> a.pop(3)  # Will return the value at index 3
4
>>> a
[1, 5, 3, 7, 8]

For remove

remove takes the parameter value and remove that value from the list.

If multiple values are present will remove the first occurrence

Note: Will throw ValueError if that value is not present

>>> a = [1, 5, 3, 4, 2, 7, 5]
>>> a.remove(5)  # removes first occurence of 5
>>> a
[1, 3, 4, 2, 7, 5]
>>> a.remove(5)
>>> a
[1, 3, 4, 2, 7]

Hope this answer is helpful.

Nitish
  • 565
  • 4
  • 16
2

The remove operation on a list is given a value to remove. It searches the list to find an item with that value and deletes the first matching item it finds. It is an error if there is no matching item, raises a ValueError.

>>> x = [1, 0, 0, 0, 3, 4, 5]
>>> x.remove(4)
>>> x
[1, 0, 0, 0, 3, 5]
>>> del x[7]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    del x[7]
IndexError: list assignment index out of range

The del statement can be used to delete an entire list. If you have a specific list item as your argument to del (e.g. listname[7] to specifically reference the 8th item in the list), it'll just delete that item. It is even possible to delete a "slice" from a list. It is an error if there index out of range, raises a IndexError.

>>> x = [1, 2, 3, 4]
>>> del x[3]
>>> x
[1, 2, 3]
>>> del x[4]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    del x[4]
IndexError: list assignment index out of range

The usual use of pop is to delete the last item from a list as you use the list as a stack. Unlike del, pop returns the value that it popped off the list. You can optionally give an index value to pop and pop from other than the end of the list (e.g listname.pop(0) will delete the first item from the list and return that first item as its result). You can use this to make the list behave like a queue, but there are library routines available that can provide queue operations with better performance than pop(0) does. It is an error if there index out of range, raises a IndexError.

>>> x = [1, 2, 3] 
>>> x.pop(2) 
3 
>>> x 
[1, 2]
>>> x.pop(4)
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    x.pop(4)
IndexError: pop index out of range

See collections.deque for more details.

Kushan Gunasekera
  • 7,268
  • 6
  • 44
  • 58
2

Remove basically works on the value . Delete and pop work on the index

Remove basically removes the first matching value. Delete deletes the item from a specific index Pop basically takes an index and returns the value at that index. Next time you print the list the value doesnt appear.

Example:

Harshal SG
  • 403
  • 3
  • 7
  • 8
    Though we thank you for your answer, it would be better if it provided additional value on top of the other answers. In this case, your answer does not provide additional value, since other users covered everything that you have included in your answer. As a secondary issue, please don't include text as pictures when you could paste it as text. If a previous answer was helpful to you, you should [vote it up](https://stackoverflow.com/help/privileges/vote-up). – David Buck Nov 28 '19 at 11:35
0

While pop and delete both take indices to remove an element as stated in above comments. A key difference is the time complexity for them. The time complexity for pop() with no index is O(1) but is not the same case for deletion of last element.

If your use case is always to delete the last element, it's always preferable to use pop() over delete(). For more explanation on time complexities, you can refer to https://www.ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt

skashyap
  • 143
  • 10
  • 4
    This is wrong in multiple ways. There is no such method as `delete`. The differences are that `pop` returns the value, and that `del` works on slices. In cases where `pop` works, `del` has exactly the same computational complexity (and is slightly faster by a constant term). – abarnert Mar 31 '18 at 09:57
0

remove(), del and pop() are slow... What about 'None'?

In the midst of so many responses, I didn't see anyone talking about performance. So I have an performance tip:

remove(), del and pop() after deletion move all remaining values ​​to the left...

1, 2, 3, 4, 5, 6
remove(3)
1, 2, <- 4, 5, 6

...making processing slow!

Changing the desired value to a null for further processing of deletions only can add a lot of speed to your program, especially when dealing with a large volume of data:

my_array[2] = None

Of course, setting a null value is different from removing it, but if you want to understand a little more about deletion, thinking about the performance of this operation also seems interesting to me.

Fellipe Sanches
  • 7,395
  • 4
  • 32
  • 33
0

Difference among del, pop & remove in terms of execution speed:

While removing any intermediate item:

import timeit
print(timeit.timeit("a=[1,2,3,4,5]\ndel a[3]",number=100000))
print(timeit.timeit("a=[1,2,3,4,5]\na.pop(3)",number=100000))
print(timeit.timeit("a=[1,2,3,4,5]\na.remove(3)",number=100000))

del vs pop vs remove:

0.019387657986953855
0.02506213402375579
0.033232167130336165

del() seems significantly faster than the other two, while remove() being the slowest.

While removing the last item:

print(timeit.timeit("a=[1,2,3,4,5]\ndel a[-1]",number=100000))
print(timeit.timeit("a=[1,2,3,4,5]\na.pop()",number=100000))
print(timeit.timeit("a=[1,2,3,4,5]\na.remove(5)",number=100000))

del vs pop vs remove:

0.01974551402963698
0.020333584863692522
0.03434014297090471

del() and pop() take similar time removing last item.

Ash Nazg
  • 514
  • 3
  • 6
  • 14
0

Is there any difference between these three methods?

The use cases are different. Here a few examples.

  • Because pop() returns the removed item, it is useful if the returned value is important. For example, it can be used to "split" a list into two using a list of indices of the list (sort of like set difference). However, since pop() changes the list, make sure that the list of indices is sorted in descending order (so that removing items from the back doesn't impact the index of the items in the front). An example:

    lst = [1, 1, 2, 30, 40, 3, 2]
    new_lst_idx = [4, 3, 0]             # sorted in descending order
    
    new_lst = [lst.pop(i) for i in new_lst_idx]  # [40, 30, 1]
    lst                                          # [1, 2, 3, 2]
    
  • del removes references to Python objects, so as other answers mentioned, a slice of a list can be removed in one go, which is much faster than removing items one-by-one. In fact, if we perform a timeit test, removing a slice takes the same time as removing an item.

    import timeit
    setup = """
    def del_slice(lst):
        del lst[-100:]
    
    def del_item(lst):
        del lst[-100]
    
    lst = list(range(10000))
    """
    t1 = min(timeit.repeat("del_slice(lst.copy())", setup, number=1000)) # 0.043364200013456866
    t2 = min(timeit.repeat("del_item(lst.copy())", setup, number=1000))  # 0.04249859999981709
    
  • remove() removes an item by value, so it can be used to filter out values but it's so slow that it's probably better to use alternative methods such as list comprehension anyway.

    As Sven Marnach's answer suggests, if you remove items from the beginning of a list, all three perform the same (then again, if this is something that is required often, then collections.deque is probably a better data structure). The following shows that there's effectively no difference between the 3 methods if the first item is removed from a list.

    setup = "lst = list(range(10000))"
    t1 = min(timeit.repeat("lst.pop(0)", setup, number=10000))          # 0.019651099981274456
    t2 = min(timeit.repeat("del lst[0]", setup, number=10000))          # 0.015160200011450797
    t3 = min(timeit.repeat("lst.remove(lst[0])", setup, number=10000))  # 0.01593300001695752
    
cottontail
  • 10,268
  • 18
  • 50
  • 51
-5

You can also use remove to remove a value by index as well.

n = [1, 3, 5]

n.remove(n[1])

n would then refer to [1, 5]

Mathias Müller
  • 22,203
  • 13
  • 58
  • 75
max runia
  • 55
  • 1
  • 49
    Try `n = [5, 3, 5]`, then `n.remove(n[2])`. – abarnert Feb 18 '14 at 03:46
  • 2
    @abarnert your use case works in sync with the below case n = [5,3,5] , then n.remove(5). Both of these remove the first encountered element from the list. – Akhil Ghatiki Mar 31 '18 at 07:24
  • 2
    @AkhilGhatiki `n.remove(n[2])` removes `n[0]`, not `n[2]`. So it’s not just linear time for no reason (maybe not a big deal when N=3), it’s also wrong (a big deal no matter what N is) – abarnert Mar 31 '18 at 09:14