Python中按索引从列表中删除元素的简明方法

Python中按索引从列表中删除元素的简明方法,python,optimization,Python,Optimization,我有一个字符列表和索引列表 myList = ['a','b','c','d'] toRemove = [0,2] 我想在一次手术中得到这个 myList = ['b','d'] 我可以做到这一点,但有没有办法做到更快 toRemove.reverse() for i in toRemove: myList.pop(i) 简明回答 >>> myList = ['a','b','c','d'] >>> toRemove = [0,2] >&g

我有一个字符列表和索引列表

myList = ['a','b','c','d']
toRemove = [0,2]
我想在一次手术中得到这个

myList = ['b','d']
我可以做到这一点,但有没有办法做到更快

toRemove.reverse()
for i in toRemove:
    myList.pop(i)
简明回答

>>> myList = ['a','b','c','d']
>>> toRemove = [0,2]
>>> 
>>> [v for i, v in enumerate(myList) if i not in toRemove]
['b', 'd']
>>> 
一艘班轮:

>>>[myList[x] for x in range(len(myList)) if not x in [0,2]]
['b', 'd']

您可以编写一个函数来为您执行此操作

def removethese(list, *args):
    for arg in args:
        del list[arg]
那就做吧

mylist = ['a', 'b', 'c', 'd', 'e']
removethese(mylist, 0, 1, 4)

我的列表现在是['c','d']

你可以像其他答案建议的那样使用列表理解,但为了让它真正更快,我建议对你想要删除的索引集使用
集合

>>> myList = ['a','b','c','d']
>>> toRemove = set([0,2])
>>> [x for i,x in enumerate(myList) if i not in toRemove]
['b', 'd']

将myList中的每个元素与toRemove中的每个元素进行比较,结果是O(n*m)(其中n是myList的长度,m是toRemove的长度)。如果使用
集合
,则检查成员身份是O(1),因此整个过程变为O(n)。但请记住,除非toRemove真的很大(比如超过1000),否则速度上的差异不会明显

如果愿意,可以使用
numpy

import numpy as np

myList = ['a','b','c','d']
toRemove = [0,2]

new_list = np.delete(myList, toRemove)
结果:

>>> new_list
array(['b', 'd'], 
      dtype='|S1')

请注意,
new\u list
是一个
numpy
数组

您给出的示例实现不正确,或者您的规范不正确。该算法删除索引0处的项,然后删除由于删除而移动到索引2的项(即,
'd'
)。我使用
删除。反向
,因此要删除的第一个元素位于索引2上,然后删除索引0上的元素。这仅在对
toRemove
列表进行排序时有效。将
toRemove
设置为一个集合,这实际上是一个非常好的算法。它是
O(m)
而不是
O(n*m)
其中
n=len(toRemove);m=len(myList)
因为它不会在每次删除项目时重复复制数组的一半。将
toRemove
a
set
设置可能是个好主意,但这取决于
toRemove
的时间长短,而
myList
是否会有所改进。我最初并不是为了简洁而写的!此实现与OP的实现一样不正确(再次假设规范是正确的)。您不认为Numpy对于一个简单的“删除数组”问题来说有点过分吗?也许OP已经在使用
Numpy
,并且所讨论的列表是数百万个元素?如果是这样的话,这可能是最快的答案。@SuperDisk,我认为
numpy
方法非常方便,可能会很有用。当然,这个任务没有“numpy”是很容易的,但是
numpy
选项值得一提。我有numpy,这正是我想要的。谢谢。@Youcha无意冒犯,但您可能应该指定下次使用的模块:)