从Python列表中删除索引列表

6

我有一个点列表(质心),其中一些点需要被移除。

如何在不使用循环的情况下完成此操作? 我尝试过这里给出的答案,但出现了以下错误:

list indices must be integers, not list

我的列表看起来像这样:

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

我希望删除 index 中的元素。最终结果应为:

centroids = [[400, 200]]

1
我已经尝试了以下内容,你尝试了什么? - Anand S Kumar
1
为什么要“不用循环”? - bruno desthuilliers
3个回答

10

您可以在列表推导式中使用 enumerate

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

请注意,最后你需要循环遍历列表以找到特殊的索引,没有任何一种方法可以在不使用循环的情况下进行此操作。但是,您可以使用列表推导式,在C语言中执行并且比Python循环(有时快2倍)更快!
此外,为了获得更好的性能,您可以将索引放在一个set容器中,其检查成员资格的时间复杂度为O(1)。

这非常快。我能建议您将j更改为其他内容(例如xv),以明确i是索引,而x/v是对象吗? - LondonRob
@LondonRob 确实,我把它改成了 element ;) - Mazdak
这将创建一个新的列表。 - mike

5
这里有另一种非常有趣的方法。
 map(centroids.__delitem__, sorted(index, reverse=True))

它实际上会就地删除项目。

+1 针对创新性解决方案。但无法测试其速度,因为它会就地修改列表(正如您所提到的)。 - LondonRob
谢谢!为什么你不能测试一下它的速度呢?也许先复制列表(以便在不破坏原始数据的情况下进行基准测试),然后使用timeit运行它?我有点好奇性能如何比较。 - Hrvoje
问题在于要运行多次速度测试(以获得准确结果),您必须为每个迭代重新创建副本;然后您必须计算出制作这些副本所花费的时间。 - Karl Knechtel
1
为什么不先复制1000次,计算所需时间,然后再进行复制和删除操作,最后相减得到结果呢? :) - Hrvoje

0

你可以使用numpy,使用delete来完成它。

例如:

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

产生

[[400, 200]]

1
这实际上比@Kasra的答案慢得多(在我的机器上大约慢10倍)。但是有多种选择总是好的。也许您可以调整示例,使其与原始帖子相同。 - LondonRob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接