1766

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

I found the list.remove method, but say I want to remove the last element, how do I do this? It seems like the default remove searches the list, but I don't want any search to be performed.

Timur Shtatland
  • 7,599
  • 2
  • 20
  • 30
Joan Venge
  • 269,545
  • 201
  • 440
  • 653
  • 13
    @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 08 '15 at 00:32
  • @J.F.Sebastian: cPython implementation, yes, thanks for correcting me. Strictly the [language spec](https://docs.python.org/2/reference/index.html) doesn't specify how to implement list, alternative implementations could choose to use a linked-list. – smci Sep 08 '15 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 '16 at 00:54
  • @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 '16 at 09:45
  • @smci if you're targeting that broadly, I'm not sure how you can hope to optimize anything. – Nick T Aug 16 '17 at 04:28
  • @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 '17 at 20:53
  • Related: *[Difference between del, remove and pop on lists](https://stackoverflow.com/questions/11520492)* – Peter Mortensen May 23 '18 at 23:35

18 Answers18

2033

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.

Neil
  • 997
  • 9
  • 24
  • 61
    Thanks, what's the difference between pop and del? – Joan Venge Mar 09 '09 at 18:34
  • 39
    del is overloaded. For example del a deletes the whole list – Brian R. Bondy Mar 09 '09 at 18:36
  • 37
    another example del a[2:4], deletes elements 2 and 3 – Brian R. Bondy Mar 09 '09 at 18:37
  • 326
    pop() returns the element you want to remove. del just deletes is. –  Mar 09 '09 at 19:14
  • `del a[-1]` implies a list traversal. `a.pop()` explicitly says it does one. – smci Aug 07 '13 at 01:31
  • 1
    @smci In what way does `del a[-1]` imply a list traversal? – glglgl Sep 07 '13 at 08:02
  • @glglgl How else could you get list element a[-1] without walking the list from a? – smci Sep 07 '13 at 08:12
  • 5
    @smci By directly going to that index. The length is known (as it is noted somewhere inside the list), and I just go to the `l-1`th reference contained in the list (which lies in memory as an array). – glglgl Sep 07 '13 at 08:14
  • No, very dangerous! You can't assume (c)Python stores lists as a contiguous array. You can verify this by declaring `y = [1,2,3,4,5,6]` then `y.insert(3,"a boring string")` then examine their ids: `[ "%0x" % id(yy) for yy in y ]`. They're non-contiguous. – smci Sep 07 '13 at 08:22
  • 1
    cPython stores lists as linked-lists: http://docs.python.org/2/c-api/list.html , to allow them to be heteregeneous. Not as arrays. – smci Sep 07 '13 at 08:24
  • 3
    @smci This is not a proof. You are comparing the IDs of the contained elements. This has nothing to do with the way the data is stored in the list. – glglgl Sep 09 '13 at 07:52
  • 14
    I cannot see a proof of "linked list" there. Look at http://svn.python.org/projects/python/trunk/Objects/listobject.c how `PyList_GetItem()` essentially returns `((PyListObject *)op) -> ob_item[i];` - the `i`th element of an array. – glglgl Sep 09 '13 at 07:53
  • 1
    I don't think you can specify a range of indexes with pop() – Valentine Bondar Sep 13 '15 at 18:43
  • In Python 3.x this does not seem to work TypeError: 'range' object doesn't support item deletion. How to do this? – gota Aug 15 '16 at 12:26
  • 1
    @Nuno Calaim: Instead of doing a = range(10), do the following: a = list(range(10)). Then try deleting. It will work. – Jadiel de Armas Oct 18 '16 at 16:26
  • what is time complexity for del operation ? if there's set of indices which have index values, and elements of respective index are to be removed from the list, is there efficient way or do we need to iterate over all index and then use delete operation that many times? @BrianR.Bondy – Murtuza Vadharia May 04 '20 at 22:37
734

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']
Jarret Hardie
  • 84,200
  • 10
  • 123
  • 121
  • 106
    Don't forget pop(-1). Yes, it's the default, but I prefer it so I don't have to remember which end pop uses by default. – S.Lott Mar 09 '09 at 18:43
  • 314
    I disagree. If you know the programmer's etymology of "pop" (it's the the operation that removes and returns the **top** of a 'stack' data structure), then `pop()` by itself is very obvious, while `pop(-1)` is potentially confusing precisely _because_ it's redundant. – coredumperror Apr 22 '13 at 22:07
  • a.pop(-1) to remove the last one? – zx1986 Jul 30 '13 at 08:56
  • 14
    @zx1986 a `pop` in most programming languages usually removes the last item, as it does in Python. So whether you specify -1 or nothing is the same. – Pascal Aug 02 '13 at 14:45
  • 36
    By the way, `pop()` returns whatever element it removed. – Bob Stein Jan 30 '16 at 10:03
  • @S.Lott: It uses the end by default because it's O(1) there; it's O(n) at the beginning. – Davis Herring Oct 01 '17 at 01:02
  • 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 05 '20 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 02 '21 at 00:09
157

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Raghav RV
  • 3,510
  • 2
  • 17
  • 26
  • 4
    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. – Mark Dickinson Jun 22 '14 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 '14 at 16:13
  • Yep, that's a bit better. Forgive me for being grumpy, but I guess what I'm trying to say is that I don't see the value of this answer: you give two methods that have already been adequately covered by other answers, and a third method (slicing) that's irrelevant because it doesn't actually solve the problem the OP asked about. – Mark Dickinson Jun 23 '14 at 07:18
  • 7
    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 '14 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 – user3085931 Mar 04 '16 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. – Yohan Obadia May 08 '17 at 07:54
56

pop is also useful to remove and keep an item from a list. Where del actually trashes the item.

>>> x = [1, 2, 3, 4]

>>> p = x.pop(1)
>>> p
    2
Cristian Ciupitu
  • 18,164
  • 7
  • 46
  • 70
boatcoder
  • 15,651
  • 16
  • 95
  • 164
32

If you want to remove the specific position element in a list, like the 2th, 3th and 7th. you can't use

del my_list[2]
del my_list[3]
del my_list[7]

Since after you delete the second element, the third element you delete actually is the fourth element in the original list. You can filter the 2th, 3th and 7th element in the original list and get a new list, like below:

new list = [j for i, j in enumerate(my_list) if i not in [2, 3, 7]]
xiaojia zhang
  • 560
  • 4
  • 7
  • Fits my need. I need to go through a list and delete some of them. So with this method I will just save in another list the indexes of the elements I want to remove, and then at the end I will use the method you gave to remove them all at once. – Magnus Jul 23 '20 at 09:42
22

It has already been mentioned how to remove a single element from a list and which advantages the different methods have. Note, however, that removing multiple elements has some potential for errors:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in indices:
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 7, 9]

Elements 3 and 8 (not 3 and 7) of the original list have been removed (as the list was shortened during the loop), which might not have been the intention. If you want to safely remove multiple indices you should instead delete the elements with highest index first, e.g. like this:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in sorted(indices, reverse=True):
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 8, 9]
nspo
  • 1,236
  • 14
  • 20
20

Generally, I am using the following method:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]
Mayur Koshti
  • 1,582
  • 13
  • 20
20

This depends on what you want to do.

If you want to return the element you removed, use pop():

>>> l = [1, 2, 3, 4, 5]
>>> l.pop(2)
3
>>> l
[1, 2, 4, 5]

However, if you just want to delete an element, use del:

>>> l = [1, 2, 3, 4, 5]
>>> del l[2]
>>> l
[1, 2, 4, 5]

Additionally, del allows you to use slices (e.g. del[2:]).

Neil
  • 997
  • 9
  • 24
19

Yet another way to remove an element(s) from a list by index.

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

# remove the element at index 3
a[3:4] = []
# a is now [0, 1, 2, 4, 5, 6, 7, 8, 9]

# remove the elements from index 3 to index 6
a[3:7] = []
# a is now [0, 1, 2, 7, 8, 9]

a[x:y] points to the elements from index x to y-1. When we declare that portion of the list as an empty list ([]), those elements are removed.

progyammer
  • 1,402
  • 3
  • 13
  • 26
14

You could just search for the item you want to delete. It is really simple. Example:

    letters = ["a", "b", "c", "d", "e"]
    letters.remove(letters[1])
    print(*letters) # Used with a * to make it unpack you don't have to (Python 3.x or newer)

Output: a c d e

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
SollyBunny
  • 491
  • 1
  • 4
  • 9
14

Use the del statement:

del listName[-N]

For example, if you want to remove the last 3 items, your code should be:

del listName[-3:]

For example, if you want to remove the last 8 items, your code should be:

del listName[-8:]
Georgy
  • 6,348
  • 7
  • 46
  • 58
lloydyu24
  • 521
  • 1
  • 6
  • 13
11

Use the following code to remove element from the list:

list = [1, 2, 3, 4]
list.remove(1)
print(list)

output = [2, 3, 4]

If you want to remove index element data from the list use:

list = [1, 2, 3, 4]
list.remove(list[2])
print(list)
output : [1, 2, 4]
Ivan Burlutskiy
  • 1,355
  • 10
  • 20
Jitesh Mohite
  • 15,430
  • 6
  • 71
  • 84
  • 2
    Comes with the caveat that your list cannot contain duplicates. – tommy.carstensen Aug 25 '18 at 15:39
  • 3
    This is not removing by index, but removing by matching value. That might be valuable information for some people visiting here, but doesn't try to answer OPs question at all. – Anthon Dec 02 '18 at 13:34
10

l - list of values; we have to remove indexes from inds2rem list.

l = range(20)
inds2rem = [2,5,1,7]
map(lambda x: l.pop(x), sorted(inds2rem, key = lambda x:-x))

>>> l
[0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Jo Ja
  • 183
  • 4
  • 14
9

As previously mentioned, best practice is del(); or pop() if you need to know the value.

An alternate solution is to re-stack only those elements you want:

    a = ['a', 'b', 'c', 'd'] 

    def remove_element(list_,index_):
        clipboard = []
        for i in range(len(list_)):
            if i is not index_:
                clipboard.append(list_[i])
        return clipboard

    print(remove_element(a,2))

    >> ['a', 'b', 'd']

eta: hmm... will not work on negative index values, will ponder and update

I suppose

if index_<0:index_=len(list_)+index_

would patch it... but suddenly this idea seems very brittle. Interesting thought experiment though. Seems there should be a 'proper' way to do this with append() / list comprehension.

pondering

litepresence
  • 2,645
  • 1
  • 24
  • 30
  • 1
    Which version of Python has a function `del()`? For that function you provide the list as the first argument to that function and then the index, or the index first and then the list? Does it return the list argument without the item, or does it do the deleting in place. I know about the `del` statement, but not about a function with the same name. – Anthon Dec 02 '18 at 13:40
9

It doesn't sound like you're working with a list of lists, so I'll keep this short. You want to use pop since it will remove elements not elements that are lists, you should use del for that. To call the last element in python it's "-1"

>>> test = ['item1', 'item2']
>>> test.pop(-1)
'item2'
>>> test
['item1']
Mo Ali
  • 611
  • 1
  • 6
  • 15
  • 1
    `pop()` and `del` both remove an element at the provided index, independent of whether that element is itself a list or not. `a = [1, [2, 3], 4]; del a[1]; b = [1, [2, 3], 4]; b.pop(1); assert a == b` – Anthon Dec 02 '18 at 14:02
7

Or if multiple indexes should be removed:

print([v for i,v in enumerate(your_list) if i not in list_of_unwanted_indexes])

Of course then could also do:

print([v for i,v in enumerate(your_list) if i != unwanted_index])
U11-Forward
  • 41,703
  • 9
  • 50
  • 73
  • 1
    Why don't you just sort the list of indices in reverse order and then delete them one by one? That way you don't have to make a new list. – Anthon Dec 02 '18 at 13:53
4

One can either use del or pop, but I prefer del, since you can specify index and slices, giving the user more control over the data.

For example, starting with the list shown, one can remove its last element with del as a slice, and then one can remove the last element from the result using pop.

>>> l = [1,2,3,4,5]
>>> del l[-1:]
>>> l
[1, 2, 3, 4]
>>> l.pop(-1)
4
>>> l
[1, 2, 3]
Bill Bell
  • 19,309
  • 5
  • 39
  • 53
pyman
  • 75
  • 1
4

You can use either del or pop to remove element from list based on index. Pop will print member it is removing from list, while list delete that member without printing it.

>>> a=[1,2,3,4,5]
>>> del a[1]
>>> a
[1, 3, 4, 5]
>>> a.pop(1)
 3
>>> a
[1, 4, 5]
>>> 
Aashutosh jha
  • 426
  • 4
  • 6