如何在循环中从Python列表中删除项目?
我试着用这段代码从一个列表中删除项目:
x = ["ok", "jj", "uy", "poooo", "fren"]
for item in x:
if len(item) != 2:
x.remove(item)
为什么 "fren"
没有从 x
中被删除呢?
5 个回答
在编程中,有时候我们会遇到一些问题,想要找到解决办法。比如说,有人可能会在网上提问,描述他们遇到的困难,或者寻求一些建议。这种情况下,其他人就会在一个叫做StackOverflow的网站上给出他们的看法和解决方案。
StackOverflow是一个专门为程序员提供帮助的平台,大家可以在这里提问、回答问题,分享经验。无论你是新手还是老手,都能在这里找到有用的信息。
当你在StackOverflow上看到一个问题时,通常会有很多人给出不同的答案。有些答案可能很简单,适合初学者;而有些答案可能比较复杂,适合有经验的人。你可以根据自己的理解能力选择合适的答案。
总之,StackOverflow是一个很好的资源,可以帮助你解决编程中的各种问题,让你在学习的过程中少走弯路。
x = [i for i in x if len(i)==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
快,因为你不需要为查找步骤付出代价,而复制步骤的成本在两种情况下是相同的。
[编辑] 这是一个非常不错的就地修改版本,复杂度是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
在遍历一个列表的时候,你不能直接从中删除项目。这样做会比较麻烦。更简单的方法是根据旧列表来创建一个新的列表:
y = [s for s in x if len(s) == 2]