5

I have a list with points (centroids) and some of them have to be removed.

How can I do this without loops? I've tried the answer given here but this error is shown:

list indices must be integers, not list

My lists look like this:

centroids = [[320, 240], [400, 200], [450, 600]]
index = [0,2]

And I want to remove the elements in index. The final result would be:

centroids = [[400, 200]]
Community
  • 1
  • 1
Thabby07
  • 125
  • 1
  • 9

3 Answers3

9

You can use enumerate within a list comprehension :

>>> centroids = [[320, 240], [400, 200], [450, 600]]
>>> index = [0,2]
>>> [element for i,element in enumerate(centroids) if i not in index]
[[400, 200]]

Note that finally you have to loop over your list to find the special indices and there is no way that do this without loop. but you can use list comprehension that performs in C language and is faster (some time 2 time faster) than python loops!

Also for getting more performance you can put your indices within a set container that has O(1) for checking membership.

kasravnd
  • 94,640
  • 16
  • 137
  • 166
3

Here's another very interesting way.

 map(centroids.__delitem__, sorted(index, reverse=True))

It will actually delete the items in-place.

Hrvoje
  • 332
  • 2
  • 6
  • +1 for an innovative solution. Can't test it for speed though, since it modifies the list in place (as you mentioned.) – LondonRob Jul 07 '15 at 11:54
  • Thanks! Why couldn't you test it for speed? Maybe copy the list first (to do the benchmark without destroying original), then run this using timeit? I'm kind of curious how performance compares. – Hrvoje Jul 07 '15 at 11:56
  • The problem is that to run multiple iterations of the speed test (required to get an accurate result), you have to re-create the copy for each iteration; and then you have to figure out how much of the time was taken in making those copies. – Karl Knechtel Jul 07 '15 at 12:05
  • Why not first make new copies 1000 times, figure out the time to do that and then make copies+do the delete, subtract the times and there you go? :) – Hrvoje Jul 07 '15 at 12:12
0

You can do it in numpy, using delete.

E.g.

 import numpy as np
 centroids = np.array([[320, 240], [400, 200], [450, 600]])
 index = [0,2]
 np.delete(arr, index, 0)

yields

[[400, 200]]
Edgar H
  • 1,032
  • 1
  • 16
  • 27
  • 1
    This is actually *much* slower than @Kasra's answer (about 10x slower on my machine). But good to have the options. Perhaps you could adjust your example so it's the same as the original post. – LondonRob Jul 07 '15 at 11:48