可能重复:
在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)
Run Code Online (Sandbox Code Playgroud)
但它不会删除"fren"
项目.有任何想法吗?
Sve*_*ach 92
迭代时,您无法从列表中删除项目.基于旧列表构建新列表要容易得多:
y = [s for s in x if len(s) == 2]
Run Code Online (Sandbox Code Playgroud)
gur*_*lex 42
hymloth和sven的答案有效,但他们不修改列表(创建一个新的).如果需要修改对象,则需要分配给切片:
x[:] = [value for value in x if len(value)==2]
Run Code Online (Sandbox Code Playgroud)
但是,对于需要删除少量元素的大型列表,这是耗费内存的,但它在O(n)中运行.
glglgl的答案受到O(n²)复杂性的影响,因为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]
Run Code Online (Sandbox Code Playgroud)
现在del x[i]
也是O(n)因为你需要在索引之后复制所有元素i
(列表是向量),所以你需要针对你的数据进行测试.仍然这应该比使用更快,remove
因为您不支付删除搜索步骤的成本,并且复制步骤成本在两种情况下都相同.
[编辑]非常好的就地,O(n)版本,内存要求有限,@Sven Marnach礼貌.它使用itertools.compress
python 2.7中引入的:
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
Run Code Online (Sandbox Code Playgroud)