删除列表中的许多元素(python)

时间:2009-09-20 02:18:35

标签: python list

我有一个清单L.

我可以删除元素i:

del L[i]

但是如果我有一组不连续的索引要删除呢?

I=set([i1, i2, i3,...])

这样做的:

for i in I: 
     del L[i]

不行。

有什么想法吗?

5 个答案:

答案 0 :(得分:31)

  

Eine Minuten bitte,Ich hap eine   kleine Problemo avec diese Religione。    - Eddie Izzard(做他的印象   马丁·路德(Martin Luther))

通过对列表进行反向迭代来删除以保留迭代器 是解决此问题的常用方法。但另一种解决方案是将其改为另一个问题。不是使用某些条件从列表中删除项目(在您的情况下,索引存在于要删除的索引列表中),而是创建一个新的列表,而不会删除违规项目。

L[:] = [ item for i,item in enumerate(L) if i not in I ]

就此而言,您首先在I中找到了哪些索引?您可以结合获取要删除的索引和构建新列表的逻辑。假设这是一个对象列表,您只想保留那些通过isValid测试的对象:

L[:] = [ item for item in L if item.isValid() ]

这比以下更简单:

I = set()
for i in range(len(L)):
    if not L[i].isValid():
        I.add(i)

for i in sorted(I, reverse=True):
    del L[i]

在大多数情况下,我将有关“如何从列表中删除我不想要的项目”的任何问题转变为“如何创建仅包含我想要的项目的新列表”。

EDITED:根据Alex Martelli对this question的回答,将“L = ......”更改为“L [:] = ...”。

答案 1 :(得分:9)

for i in I:
    del L[i]

将无效,因为(取决于顺序)您可能使迭代器无效 - 这通常会显示为您要删除的一些项目保留在列表中。

按照索引的相反顺序从列表中删除项目总是安全的。最简单的方法是使用sorted():

for i in sorted(I, reverse=True):
    del L[i]

答案 2 :(得分:4)

您可以按如下方式使用numpy.delete

import numpy as np
a = ['a', 'l', 3.14, 42, 'u']
I = [1, 3, 4]
np.delete(a, I).tolist()
# Returns: ['a', '3.14']

如果您不介意最后使用numpy数组,则可以省略.tolist()。您应该看到一些非常重要的速度改进,使其成为一个更具可扩展性的解决方案。我没有对它进行基准测试,但numpy操作是用C或Fortran编写的编译代码。

答案 3 :(得分:1)

如果原始列表数据可以安全地转换为集合(即所有唯一值并且不需要维护顺序),您还可以使用集合操作:

Lset = set(L)
newset = Lset.difference(I)

你也可以用Bag / Multiset做点什么,虽然它可能不值得努力。 Paul McGuire的第二个listcomp解决方案对于大多数情况来说当然是最好的。

答案 4 :(得分:0)

L = [ item for item in L if L.index(item) not in I ]