如何在循环中从python列表中移除项?

2024-06-01 02:46:03 发布

您现在位置:Python中文网/ 问答频道 /正文

Possible Duplicate:
Remove items from a list while iterating in 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"项。有什么想法吗?


Tags: infrom列表lenitemsokitemremove
3条回答
x = [i for i in x if len(i)==2]

在列表上迭代时,不能从列表中删除项。在旧列表的基础上创建新列表要容易得多:

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

hymloth和sven的答案有效,但它们不会修改列表(创建一个新的列表)。如果需要修改对象,则需要指定给切片:

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

但是,对于需要删除很少元素的大型列表,这会占用内存,但它在O(n)中运行。

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

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

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(列表是一个向量)之后的所有元素,所以您需要根据您的数据测试它。不过,这应该比使用remove更快,因为您不支付remove的搜索步骤的成本,而且在这两种情况下,复制步骤的成本都是相同的。

[编辑]非常好的地方,O(n)版本的有限内存要求,由@Sven Marnach提供。它使用了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

相关问题 更多 >