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:
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]
In : remove_indices = [1,2,3] In : somelist = range(10) In : somelist = [i for j, i in enumerate(somelist) if j not in remove_indices] In : somelist Out: [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:
0:5,7,9])) array([5, 6, 8])np.delete(a,(np.r_[
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 : mylist = [‘a’,’b’,’c’,’d’,’charles’]
In : for x in range(len(mylist)):
In : multipop(mylist, [0, 2, 4])
Out: [‘charles’, ‘c’, ‘a’]
In : mylist
Out: [‘b’, ‘d’]