Categories
indexing list python

How to remove an element from a list by index

2047

How do I remove an element from a list by index?

I found list.remove(), but this slowly scans the list for an item by value.

7

  • 16

    @smci: Python list is array-based: to delete an item in the middle, you have to move all items on the right to remove the gap that is why it is O(n) in time operation. deque() provides efficient operations on both ends but it does not provide O(1) insertions/lookups/deletions in the middle.

    – jfs

    Sep 8, 2015 at 0:32

  • 1

    @J.F.Sebastian: cPython implementation, yes, thanks for correcting me. Strictly the language spec doesn’t specify how to implement list, alternative implementations could choose to use a linked-list.

    – smci

    Sep 8, 2015 at 19:35


  • @smci: no practical Python implementation would use O(n) index access a[i] (due to linked-lists). Note: array-based implementation provides O(1) index access.

    – jfs

    Feb 23, 2016 at 0:54

  • 2

    @J.F.Sebastian: of course. I merely noted that the language spec does not define this, it’s an implementation issue. (I was surprised to find that it didn’t.)

    – smci

    Feb 27, 2016 at 9:45

  • 1

    @NickT: I’m merely cautioning to distinguish when something is implementation-defined due to not being defined in the language spec. It was exactly that sort of assumption that caused major grief with hash instability (between platforms) back in 2.x. Obviously most rational implementations of Python’s list would never choose linked-list since we want the basic operations to be O(1). That’s all.

    – smci

    Aug 20, 2017 at 20:53


2307

Use del and specify the index of the element you want to delete:

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del a[-1]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8]

Also supports slices:

>>> del a[2:4]
>>> a
[0, 1, 4, 5, 6, 7, 8, 9]

Here is the section from the tutorial.

17

  • 69

    Thanks, what’s the difference between pop and del?

    Mar 9, 2009 at 18:34

  • 44

    del is overloaded. For example del a deletes the whole list

    Mar 9, 2009 at 18:36

  • 39

    another example del a[2:4], deletes elements 2 and 3

    Mar 9, 2009 at 18:37

  • 343

    pop() returns the element you want to remove. del just deletes is.

    – unbeknown

    Mar 9, 2009 at 19:14

  • 14

    I cannot see a proof of “linked list” there. Look at svn.python.org/projects/python/trunk/Objects/listobject.c how PyList_GetItem() essentially returns ((PyListObject *)op) -> ob_item[i]; – the ith element of an array.

    – glglgl

    Sep 9, 2013 at 7:53

843

You probably want pop:

a = ['a', 'b', 'c', 'd']
a.pop(1)

# now a is ['a', 'c', 'd']

By default, pop without any arguments removes the last item:

a = ['a', 'b', 'c', 'd']
a.pop()

# now a is ['a', 'b', 'c']

6

  • 52

    By the way, pop() returns whatever element it removed.

    – Bob Stein

    Jan 30, 2016 at 10:03

  • @S.Lott: It uses the end by default because it’s O(1) there; it’s O(n) at the beginning.

    Oct 1, 2017 at 1:02

  • 1

    This answer is incorrect. pop() returns the value removed from the array, not the array without the value you wanted to remove as shown in the code’s comments. I believe that it doesn’t answer the original question, as it was not asked how to extract a value from an array but to remove it.

    – Seb

    Dec 5, 2020 at 12:54


  • @Seb, You’re correct in that it returns the value you delete, but there’s no requirement in the question saying the list had to be regenerated or returned. Since pop mutates the list in place, it fulfills the requirements set forth by the question exactly, albeit with a superfluous return value. I’d even argue that pop is more correct than the accepted answer, since del is a keyword that’s linked pretty closely to the memory management of the running program, compared to list.pop, which is a feature of the list object in Python.

    – b4ux1t3

    Mar 2, 2021 at 0:09

  • in summary, do I use del or pop to modify and delete that element with no weird errors?

    Sep 16, 2021 at 16:48

179

Like others mentioned pop and del are the efficient ways to remove an item of given index. Yet just for the sake of completion (since the same thing can be done via many ways in Python):

Using slices (this does not do in place removal of item from original list):

(Also this will be the least efficient method when working with Python list, but this could be useful (but not efficient, I reiterate) when working with user defined objects that do not support pop, yet do define a __getitem__ ):

>>> a = [1, 2, 3, 4, 5, 6]
>>> index = 3 # Only positive index

>>> a = a[:index] + a[index+1 :]
# a is now [1, 2, 3, 5, 6]

Note: Please note that this method does not modify the list in place like pop and del. It instead makes two copies of lists (one from the start until the index but without it (a[:index]) and one after the index till the last element (a[index+1:])) and creates a new list object by adding both. This is then reassigned to the list variable (a). The old list object is hence dereferenced and hence garbage collected (provided the original list object is not referenced by any variable other than a).

This makes this method very inefficient and it can also produce undesirable side effects (especially when other variables point to the original list object which remains un-modified).

Thanks to @MarkDickinson for pointing this out …

This Stack Overflow answer explains the concept of slicing.

Also note that this works only with positive indices.

While using with objects, the __getitem__ method must have been defined and more importantly the __add__ method must have been defined to return an object containing items from both the operands.

In essence, this works with any object whose class definition is like:

class foo(object):
    def __init__(self, items):
        self.items = items

    def __getitem__(self, index):
        return foo(self.items[index])

    def __add__(self, right):
        return foo( self.items + right.items )

This works with list which defines __getitem__ and __add__ methods.

Comparison of the three ways in terms of efficiency:

Assume the following is predefined:

a = range(10)
index = 3

The del object[index] method:

By far the most efficient method. It works will all objects that define a __del__ method.

The disassembly is as follows:

Code:

def del_method():
    global a
    global index
    del a[index]

Disassembly:

 10    0 LOAD_GLOBAL     0 (a)
       3 LOAD_GLOBAL     1 (index)
       6 DELETE_SUBSCR   # This is the line that deletes the item
       7 LOAD_CONST      0 (None)
      10 RETURN_VALUE
None

pop method:

It is less efficient than the del method and is used when you need to get the deleted item.

Code:

def pop_method():
    global a
    global index
    a.pop(index)

Disassembly:

 17     0 LOAD_GLOBAL     0 (a)
        3 LOAD_ATTR       1 (pop)
        6 LOAD_GLOBAL     2 (index)
        9 CALL_FUNCTION   1
       12 POP_TOP
       13 LOAD_CONST      0 (None)
       16 RETURN_VALUE

The slice and add method.

The least efficient.

Code:

def slice_method():
    global a
    global index
    a = a[:index] + a[index+1:]

Disassembly:

 24     0 LOAD_GLOBAL    0 (a)
        3 LOAD_GLOBAL    1 (index)
        6 SLICE+2
        7 LOAD_GLOBAL    0 (a)
       10 LOAD_GLOBAL    1 (index)
       13 LOAD_CONST     1 (1)
       16 BINARY_ADD
       17 SLICE+1
       18 BINARY_ADD
       19 STORE_GLOBAL   0 (a)
       22 LOAD_CONST     0 (None)
       25 RETURN_VALUE
None

Note: In all three disassembles ignore the last two lines which basically are return None. Also the first two lines are loading the global values a and index.

6

  • 6

    Your slicing method does not remove an element from a list: instead it creates a new list object containing all but the ith entry from the original list. The original list is left unmodified.

    Jun 22, 2014 at 15:28

  • @MarkDickinson Have edited the answer to clarify the same … Please let me know if it looks good now ?

    – Raghav RV

    Jun 22, 2014 at 16:13

  • 8

    Maybe the answer wasn’t entirely on topic, but the indexing method is useful if you need to omit an item from an immutable object, such as a tuple. pop() and del() will not work in that case.

    – Caleb

    Dec 18, 2014 at 17:31

  • 7

    @rvraghav93 out of all presented methods during the entire post, the a = a[:index] + a[index+1 :]-trick was the savest, when it comes to huge lists. All the other methods ended up in a deadlock. So thank you very much

    Mar 4, 2016 at 18:38

  • 4

    Indeed Mark, you are grumpy. This answer is the one I prefered because it was really pedagogical. I learned most from this answer and the desassembly details that were provided and the impact on performanc. Plus the slicing method, yes, create another object, but now it is specified and sometimes that is also what you need.

    May 8, 2017 at 7:54