How to remove multiple indexes from a list at once?

Let's say I have this list here:

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

How can I remove indexes 2, 3, 4 and 5 at the same time?

pop does not accept multiple values. How else will I do it?

+56
python
Jul 03 2018-12-12T00:
source share
8 answers

You need to do this in a loop, there is no built-in operation to delete multiple indexes at once.

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

 del my_list[2:6] 

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

It is not clear from your question whether you really need to delete an arbitrary set of indices or if it will always be a continuous 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 as not to discard subsequent indexes.

+83
Jul 03 2018-12-12T00:
source share
 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] 
+17
Jul 03 2018-12-12T00:
source share

If they are adjacent, you can simply do

 x[2:6] = [] 

If you want to remove non-contiguous indexes, this is a little trickier.

 x = [v for i,v in enumerate(x) if i not in frozenset((2,3,4,5))] 
+8
Jul 03 2018-12-12T00:
source share
 lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g']; lst = lst[0:2] + lst[6:] 

This is a one step operation. It does not use a loop and therefore is fast. It uses list sorting.

+4
Dec 12 '16 at 9:34
source share

If you can use numpy , you can remove multiple indexes:

 >>> 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 separate indices:

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

However, removal is not in place , so you need to assign it to it.

+3
Jul 03 '12 at 9:22
source share

There wasn’t a big hint of performance for different ways, so I ran a test to remove 5,000 elements from 50,000 in all three common approaches, and for me there was a numpy winner (if you have elements that fit in numpy)

  • 7.5 sec to understand the list
  • 0.08 s to remove items in reverse order
  • 0.009 sec for numpy.delete

Here is the code that I programmed (in the third conversion of the function from / to the list, you can delete it if the numpy arrays work fine):

 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, l)) l = range(50000) random.shuffle(l) remove_id = random.sample(range(len(l)), 5000) # 10% ==> 5000 # ... 
+3
Dec 10 '16 at 20:09
source share

Old question, but I have an answer.

First, consider the list items as follows:

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

Then call this function with a list of indexes of the elements you want to place. It is strong enough that the order of the list does not 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, the result should contain only those elements that you want to delete.

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

In [76]: for x in the 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']

0
Jul 07 '16 at 19:48
source share

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] 
0
Jul 02 '17 at 14:16
source share



All Articles