在Python中从列表中删除多个项

在Python中从列表中删除多个项,python,list,Python,List,例如,我得到了一个列表:myList=[“asdf”、“ghjk”、“qwer”、“tyui”] 我还有一个要删除的项目的索引号列表:removeIndexList=[1,3](我要从上面的列表中删除项目1和3) 执行此操作的最佳方法是什么?使用列表理解和枚举(): 将removelist改为set将有助于加快进度: removeset = set(removelist) newlist = [v for i, v in enumerate(oldlist) if i not in remove

例如,我得到了一个列表:
myList=[“asdf”、“ghjk”、“qwer”、“tyui”]

我还有一个要删除的项目的索引号列表:
removeIndexList=[1,3]
(我要从上面的列表中删除项目1和3)


执行此操作的最佳方法是什么?

使用列表理解和
枚举()

removelist
改为
set
将有助于加快进度:

removeset = set(removelist)
newlist = [v for i, v in enumerate(oldlist) if i not in removeset]
演示:


显而易见的方法行不通:

list=["asdf","ghjk","qwer","tyui"]
removelist=[1,3] 
for index in removelist:
    del list[index]
问题是,删除#1“ghjk”后,之后的所有内容都会向前移动。所以#3不再是“tyui”,它已经超过了列表的末尾


您可以通过确保向后行走来解决此问题:

list=["asdf","ghjk","qwer","tyui"]
removelist=[1,3] 
for index in sorted(removelist, reverse=True):
    del list[index]

然而,正如Martijn Pieters所建议的那样,通常最好只构建一个新的过滤列表:

list = [v for i, v in enumerate(list) if i not in removelist]

作为旁注,不要称你的列表为
list
;这隐藏了内置类型/构造函数。我这么问是因为可能有更好的方法来做,而不是做一个看起来像管道胶带的循环。我在列表中使用了这个名字,因为这是一个例子,我不认为这有什么大不了的。即使你不喜欢你写它的方式,告诉我们你写它的方式。首先,这意味着如果您的问题的细节不完全清楚,我们可以运行您的代码来了解您的意图。另一方面,它让我们了解您的经验,因此我们可以适当地确定答案。最后,许多人甚至不会看一个没有任何工作的问题,假设你只是懒惰;这一次你很幸运,得到了一个很好的答案,但如果你吓跑了一半的潜在回答者,你就必须加倍幸运……这不是一个“帮我修复代码”的问题。这是一个“什么是归档x的最佳方式”的问题。我只是告诉你我的代码看起来像“管道胶带”,因为是你自找的。除此之外,这是无关紧要的。不,我不懒惰。我问的是一个真实的问题,我已经寻找了30分钟的答案。我已经在问题中加入了所有需要回答的信息。为什么您认为一段代码在这种情况下会有所帮助?我不是说你懒惰,我是说这里(以及许多其他地方)一半的人会不公平地认为你懒惰,而跳过你的问题,使你得到好答案的可能性只有一半。不管怎样,你可能会很幸运,就像你所做的那样,但是为什么要依赖于它呢?我没有用
排序(…,reverse=True)
,而是用
reversed
做了同样的事情,并取得了巨大的成功。@SethMMorton:只有当你知道
removelist
被保证按正向顺序排序时,这才有效。(如果你只知道这一点,因为你把这个列表显式地写为一个文本,那么你最好先把它倒过来写。)我明白你的意思。我没有仔细看你的算法。是的,在这个方法中,你无论如何都需要排序。我知道这个方法很旧,但是你能解释一下它是如何工作的吗
v for i
是一个我还没有遇到的构造,那么列表中包含的所有内容似乎都很有趣,但可以理解,如果我不在removelist中,那么我可以理解
,以帮助创建没有这些内容的新列表。但是我不太确定这里发生了什么。当
len(removelist)
为2时,我怀疑这个集合是否有用。尤其是当
len(list)
仅为4时。事实上:
%timeit[v代表i,如果我不在r中,枚举(a)中的v]
给我1.15us
%timeit[v代表i,如果i不在集合(r)中,则枚举(a)中的v)]
2.39,因此速度要慢50%。(其中只有290ns是
set(r)
调用;其余的是散列和查找散列所需的时间比遍历2元素列表所需的时间更长。)@abarnert:if
表达式是为每个元素执行的,因此每个循环都要创建一个新的集合。@abarnert:当然,非常小的输入将以恒定的成本进行,但一般来说,使用
集合
进行成员资格测试将击败针对列表的成员资格测试,不是吗?@abarnert:如果要删除的项目序列长度未知,我还是选择集合;另一种方法是收集要删除的项目的预期数量的统计数据。@abarnert,有很多故事,人们都懒得使用像这样的简单优化。如果系统以后需要扩展,它不会对小案例造成伤害,也可以避免悲伤。特别是当最初的开发人员已经离开,并且它处于某种深度但经常使用的功能中时。
list=["asdf","ghjk","qwer","tyui"]
removelist=[1,3] 
for index in sorted(removelist, reverse=True):
    del list[index]
list = [v for i, v in enumerate(list) if i not in removelist]