# How to remove multiple indexes from a list at the same time? [duplicate]

Posted on

### Question :

How to remove multiple indexes from a list at the same time? [duplicate]

Say I have this list here:

``````list = [a, b, c, d, e, f, g]
``````

How would I delete say indexes `2, 3, 4`, and `5` at the same time?

pop doesn’t accept multiple values. How else do I do this?

You need to do this in a loop, there is no built-in operation to remove a number of indexes at once.

Your example is actually a contiguous sequence of indexes, so you can do this:

``````del my_list[2:6]
``````

which removes the slice starting at 2 and ending just before 6.

It isn’t clear from your question whether in general you need to remove an arbitrary collection of indexes, or if it will always be a contiguous sequence.

If you have an arbitrary collection of indexes, then:

``````indexes = [2, 3, 5]
for index in sorted(indexes, reverse=True):
del my_list[index]
``````

Note that you need to delete them in reverse order so that you don’t throw off the subsequent indexes.

``````remove_indices = [1,2,3]
somelist = [i for j, i in enumerate(somelist) if j not in remove_indices]
``````

Example:

``````In [9]: remove_indices = [1,2,3]

In [10]: somelist = range(10)

In [11]: somelist = [i for j, i in enumerate(somelist) if j not in remove_indices]

In [12]: somelist
Out[12]: [0, 4, 5, 6, 7, 8, 9]
``````

There wasn’t much hint on performance for the different ways so I performed a test on removing 5000 items from 50000 in all 3 generally different approaches, and for me numpy was the winner (if you have elements that fit in numpy):

• 7.5 sec for the enumerated list comprehension [4.5 sec on another PC]
• 0.08 sec for deleting items in reverse order [0.017 (!) sec]
• 0.009 sec for numpy.delete [0.006 sec]

Here’s the code I timed (in the third function conversion from/to list may be removed if working directly on numpy arrays is ok):

``````import time
import numpy as np
import random

def del_list_indexes(l, id_to_del):
somelist = [i for j, i in enumerate(l) if j not in id_to_del]
return somelist

def del_list_inplace(l, id_to_del):
for i in sorted(id_to_del, reverse=True):
del(l[i])

def del_list_numpy(l, id_to_del):
arr = np.array(l, dtype='int32')
return list(np.delete(arr, id_to_del))

l = range(50000)
random.shuffle(l)
remove_id = random.sample(range(len(l)), 5000) # 10% ==> 5000

# ...
``````

If they’re contiguous, you can just do

``````x[2:6] = []
``````

If you want to remove noncontiguous indexes, it’s a little trickier.

``````x = [v for i,v in enumerate(x) if i not in frozenset((2,3,4,5))]
``````

If you can use numpy, then you can delete multiple indices:

``````>>> import numpy as np
>>> a = np.arange(10)
>>> np.delete(a,(1,3,5))
array([0, 2, 4, 6, 7, 8, 9])
``````

and if you use `np.r_` you can combine slices with individual indices:

``````>>> np.delete(a,(np.r_[0:5,7,9]))
array([5, 6, 8])
``````

However, the deletion is not `in place`, so you have to assign to it.

``````lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
lst = lst[0:2] + lst[6:]
``````

This is a single step operation. It does not use a loop and therefore executes fast. It uses list slicing.

another option (in place, any combination of indices):

``````_marker = object()

for i in indices:
my_list[i] = _marker  # marked for deletion

obj[:] = [v for v in my_list if v is not _marker]
``````

Old question, but I have an answer.

First, peruse the elements of the list like so:

``````for x in range(len(yourlist)):
print '%s: %s' % (x, yourlist[x])
``````

Then, call this function with a list of the indexes of elements you want to pop. It’s robust enough that the order of the list doesn’t matter.

``````def multipop(yourlist, itemstopop):
result = []
itemstopop.sort()
itemstopop = itemstopop[::-1]
for x in itemstopop:
result.append(yourlist.pop(x))
return result
``````

As a bonus, result should only contain elements you wanted to remove.

In [73]: mylist = [‘a’,’b’,’c’,’d’,’charles’]

In [76]: for x in range(len(mylist)):

``````      mylist[x])
``````

….:

0: a

1: b

2: c

3: d

4: charles

In [77]: multipop(mylist, [0, 2, 4])

Out[77]: [‘charles’, ‘c’, ‘a’]

In [78]: mylist

Out[78]: [‘b’, ‘d’]