如果条件为真,如何从Python列表中删除项目?

可能重复:
在Python中迭代时从列表中删除项目

我试图从列表中删除一个项目在Python中:

x = ["ok", "jj", "uy", "poooo", "fren"] for item in x: if len(item) != 2: print "length of %s is: %s" %(item, len(item)) x.remove(item) 

但它并没有删除"fren"项目。 有任何想法吗?

迭代时无法从列表中删除项目。 build立一个基于旧的名单更容易:

 y = [s for s in x if len(s) == 2] 

hymloth和sven的答案有效,但是他们不修改列表(创build一个新列表)。 如果您需要修改对象,则需要将其分配给切片:

 x[:] = [value for value in x if len(value)==2] 

但是,对于需要删除less量元素的大型列表,这是消耗内存,但是它运行在O(n)中。

glglgl的答案遭受O( list.remove )的复杂性,因为list.remove是O(n)。

根据您的数据结构,您可能更喜欢注意删除元素的索引,并使用del keywork通过索引删除:

 to_remove = [i for i, val in enumerate(x) if len(val)==2] for index in reversed(to_remove): # start at the end to avoid recomputing offsets del x[index] 

现在del x[i]也是O(n),因为你需要复制索引i后面的所有元素(一个列表是一个向量),所以你需要对你的数据进行testing。 不过,这应该比使用remove更快,因为您不需要支付search删除步骤的成本,并且复制步骤的成本在两种情况下都是相同的。

非常好的就地,O(n)版本有限的内存要求,由@Sven Marnach提供 。 它使用python 2.7中引入的itertools.compress

 from itertools import compress selectors = (len(s) == 2 for s in x) for i, s in enumerate(compress(x, selectors)): # enumerate elements of length 2 x[i] = s # move found element to beginning of the list, without resizing del x[i+1:] # trim the end of the list 
 x = [i for i in x if len(i)==2] 

这源于删除时,迭代跳过一个元素,因为它只能在索引上工作。

解决方法可能是:

 x = ["ok", "jj", "uy", "poooo", "fren"] for item in x[:]: # make a copy of x if len(item) != 2: print "length of %s is: %s" %(item, len(item)) x.remove(item) 

已经提到的列表理解方法可能是你最好的select。 但是,如果你绝对想要做到这一点(例如,如果x是真的很大),这里有一个方法:

 x = ["ok", "jj", "uy", "poooo", "fren"] index=0 while index < len(x): if len(x[index]) != 2: print "length of %s is: %s" %(x[index], len(x[index])) del x[index] continue index+=1