【问题标题】:Easy way to delete elements from a list in Python [duplicate]从Python列表中删除元素的简单方法[重复]
【发布时间】:2011-03-17 13:00:11
【问题描述】:

可能重复:
Removing an element from a list based on a predicate

假设我有一个列表,我想从中删除符合条件的元素,我怎样才能更容易地实现呢?

我试过了:

for i in range (len(list)):    
     if [condition]:
        del(list[i]);

显然它不起作用...我心中唯一的解决方案是向左移动以替换我要删除的元素,然后删除最后一个元素。无论如何有更快的解决方案吗?

【问题讨论】:

  • 不要使用list作为变量名。
  • 根据索引从列表中删除项目时循环遍历列表是不好的。另外,我会避免将您的列表变量命名为“列表”

标签: python list


【解决方案1】:

如何使用列表推导:

mylist = [x for x in mylist if not condition]

【讨论】:

  • 谢谢!非常有用且简单
【解决方案2】:

最简单的方法是使用filter 创建列表的副本:

list_removed = filter(lambda item: not condition(item), list)

【讨论】:

  • 你的意思是lambda item: not condition
  • @Hugh:我确实做到了。感谢您发现并修复。
【解决方案3】:

我推荐@Space_C0wb0y 的解决方案;但是,为了完整起见,我想指出

for i in range(len(lst)-1, -1, -1):    
    if (condition):
        del lst[i]

工作正常。

【讨论】:

  • 它可以工作,但是是 O(n^2),而列表理解或 filter 调用是 O(n)。这可能并不总是很重要,但列表理解不太可能是错误的选择。
  • @Duncan:不是在争论,但是你怎么得到 O(n**2)?
  • 我相信这是因为每次删除列表中的一个项目时,所有尾随项​​目都会向下移动一个。请参阅此答案的结尾,以了解(我认为!)避免此问题的就地、保留顺序的过滤器:stackoverflow.com/questions/5162991/…
  • 正如@senderle 所说,每次删除都必须围绕指向其后每个元素的指针进行洗牌。 @senerle,您可以使用切片分配对列表进行就地过滤或列表理解:lst[:] = [...]
  • @Duncan -- 啊!切片分配......现在看起来很明显。 :) 但是列表理解仍然不会创建副本吗?使用生成器表达式会避免这种情况吗?
【解决方案4】:

如果您需要就地修改列表(以便其他人对filter 或列表理解的建议对您没有帮助),那么:

  1. 您可以通过以相反的顺序处理元素来避免您给出的代码完全失败,这样删除一个不会影响后面处理的编号。

  2. 移动元素以将“死”的元素放在最后几乎肯定不值得,但如果你这样做,你可以通过在最后进行一次删除以删除所有元素来获得更多的优化死元素,而不是像你看到的那样删除每个元素。 (这样做的好处可能很小。删除列表的最后一个元素很便宜,除非它碰巧触发了实际的调整大小,根据设计它不会经常这样做。)

  3. 如果碰巧您要删除很多元素(列表中所有元素的很大一部分),那么上面 2 中的“不值得”就不那么明显了,您应该进行基准测试两种方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 2012-05-09
    • 2018-01-01
    • 2021-01-19
    • 2016-12-27
    相关资源
    最近更新 更多