2

How to delete all the elements from a list that have their corresponding index in another list?

a = [1,13,15,16,22,70,3]
index_list = [3,6]

So the final list should look like this:

a = [1,13,15,22,70] # because we removed the elements that have their index equal to 3 and 6.

I tried this, but as the length of the list is modified because of the deletion, it destroys the proper removing:

i = 0
while i < len(a):
     del a[index_list[i]]
     i +=1
     if (i < len(a)-1):
        index_list[i+1] = index_list[i+1] - 1 

And I got an error.

How can I make this work?

Ariadne R.
  • 452
  • 11
  • 24

4 Answers4

2
result = [i for j, i in enumerate(a) if j not in index_list]

from: Deleting multiple elements from a list, or less pythonic:

result = []
for i, j in enumerate(a):
    if j not in index_list:
        result.add(i)
Simon Tulling
  • 176
  • 1
  • 7
  • note: if `index_list` is longer than couple dozen of indexes, it's better to convert it to a set first. – Marat Aug 16 '20 at 17:25
2

try this

a = [e for i, e in enumerate(a) if i not in index_list]
Kuldip Chaudhari
  • 1,112
  • 4
  • 8
1

If returning a new object with the same data is ok, use a list comprehension:

a = [val for j, val in enumerate(a) if j not in index_list]

Sometimes however, you may want to modify the original object in-place. In that case you could do something like this:

# get index list in reverse order
drop_inds = sorted(index_list, reverse=True)

# drop elements in-place
for idx in drop_inds:
    del a[idx]
anon01
  • 10,618
  • 8
  • 35
  • 58
  • It's also faster, btw. Imagine for example the extreme case where we want to delete *all* elements. Deleting front to back would take quadratic time, while deleting back to front would take linear time. – superb rain Aug 16 '20 at 17:53
1

Assuming index_list contents are valid for as actual size, you won't have a problem if you delete from the end of the list to the start:

a = [1,13,15,16,22,70,3]
index_list = [3,6]
for pos in reversed(index_list):
    a.pop(pos)
print(f"{a=}")

To make it into a more capable one-line which strips out duplicates in the removal list and returns what was removed:

a = [1,13,15,16,22,70,3]
index_list = [3,6,6]

print(f"before:{a=}")
removed = [a.pop(pos) for pos in reversed(list(set(index_list)))]

print(f"{removed=}")
print(f"after :{a=}")

output:

before:a=[1, 13, 15, 16, 22, 70, 3]
removed=[3, 16]
after :a=[1, 13, 15, 22, 70]

output:

a=[1, 13, 15, 22, 70]

You could even add a bit of filtering to take out indices in the removal list that are not in the bounds of as length.

JL Peyret
  • 10,917
  • 2
  • 54
  • 73