如果条件为真,如何从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