如何通过索引从列表中删除元素

如何从列表按指数中删除元素?

我找到了list.remove(),但这会慢慢地扫描列表中的项目按价值

3661113 次浏览

你可能想要pop

a = ['a', 'b', 'c', 'd']a.pop(1)
# now a is ['a', 'c', 'd']

默认情况下,pop不带任何参数删除最后一项:

a = ['a', 'b', 'c', 'd']a.pop()
# now a is ['a', 'b', 'c']

使用del并指定要删除的元素的索引:

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> del a[-1]>>> a[0, 1, 2, 3, 4, 5, 6, 7, 8]

还支持切片:

>>> del a[2:4]>>> a[0, 1, 4, 5, 6, 7, 8, 9]

这里是教程中的部分。

#0对于从列表中删除和保留项目也很有用。其中del实际上丢弃了该项目。

>>> x = [1, 2, 3, 4]
>>> p = x.pop(1)>>> p2

像其他人提到的pop和del是删除给定索引项的有效方法。然而,只是为了完成(因为在Python中可以通过多种方式完成同样的事情):

使用切片(这不会从原始列表中删除项目):

(在使用Python列表时,这也是效率最低的方法,但在使用不支持pop的用户定义对象时,这可能很有用(但效率不高,我重申),但确实定义了__getitem__):

>>> a = [1, 2, 3, 4, 5, 6]>>> index = 3 # Only positive index
>>> a = a[:index] + a[index+1 :]# a is now [1, 2, 3, 5, 6]

备注:请注意,此方法不会像popdel那样修改列表。而是制作两个列表副本(一个从开始到索引,但没有索引(a[:index]),一个在索引之后直到最后一个元素(a[index+1:])),并通过添加两者来创建一个新的列表对象。然后将其重新分配给列表变量(a)。因此,旧列表对象被取消引用并因此被垃圾收集(前提是原始列表对象不被a以外的任何变量引用)。

这使得这种方法非常低效,并且还会产生不希望的副作用(尤其是当其他变量指向未修改的原始列表对象时)。

感谢@MarkDickinson指出这一点…

这个堆栈溢出答案解释了切片的概念。

另请注意,这仅适用于正指数。

与对象一起使用时,必须定义__getitem__方法,更重要的是必须定义#1方法以返回包含两个操作数中的项的对象。

本质上,这适用于任何类定义如下的对象:

class foo(object):def __init__(self, items):self.items = items
def __getitem__(self, index):return foo(self.items[index])
def __add__(self, right):return foo( self.items + right.items )

这适用于list,它定义了__getitem____add__方法。

三种方法在效率方面的比较:

假设以下是预定义的:

a = range(10)index = 3

del object[index]方法:

迄今为止最有效的方法。它适用于定义__del__方法的所有对象。

拆解如下:

代码:

def del_method():global aglobal indexdel a[index]

拆卸:

 10    0 LOAD_GLOBAL     0 (a)3 LOAD_GLOBAL     1 (index)6 DELETE_SUBSCR   # This is the line that deletes the item7 LOAD_CONST      0 (None)10 RETURN_VALUENone

pop方法:

它的效率低于del方法,并且在需要获取已删除的项目时使用。

代码:

def pop_method():global aglobal indexa.pop(index)

拆卸:

 17     0 LOAD_GLOBAL     0 (a)3 LOAD_ATTR       1 (pop)6 LOAD_GLOBAL     2 (index)9 CALL_FUNCTION   112 POP_TOP13 LOAD_CONST      0 (None)16 RETURN_VALUE

切片和添加方法。

效率最低的。

代码:

def slice_method():global aglobal indexa = a[:index] + a[index+1:]

拆卸:

 24     0 LOAD_GLOBAL    0 (a)3 LOAD_GLOBAL    1 (index)6 SLICE+27 LOAD_GLOBAL    0 (a)10 LOAD_GLOBAL    1 (index)13 LOAD_CONST     1 (1)16 BINARY_ADD17 SLICE+118 BINARY_ADD19 STORE_GLOBAL   0 (a)22 LOAD_CONST     0 (None)25 RETURN_VALUENone

注意:在所有三个反汇编中,忽略最后两行基本上是return None。前两行还加载全局值aindex

一般来说,我使用以下方法:

>>> myList = [10,20,30,40,50]>>> rmovIndxNo = 3>>> del myList[rmovIndxNo]>>> myList[10, 20, 30, 50]

可以使用del或pop,但我更喜欢del,因为您可以指定索引和切片,让用户对数据有更多的控制权。

例如,从显示的列表开始,可以使用del作为切片删除其最后一个元素,然后可以使用pop从结果中删除最后一个元素。

>>> l = [1,2,3,4,5]>>> del l[-1:]>>> l[1, 2, 3, 4]>>> l.pop(-1)4>>> l[1, 2, 3]

如前所述,最佳实践是del();或pop(),如果您需要知道值。

另一种解决方案是只重新堆叠你想要的那些元素:

    a = ['a', 'b', 'c', 'd']
def remove_element(list_,index_):clipboard = []for i in range(len(list_)):if i is not index_:clipboard.append(list_[i])return clipboard
print(remove_element(a,2))
>> ['a', 'b', 'd']

eta:嗯…不会对负指数值起作用,会思考和更新

我猜

if index_<0:index_=len(list_)+index_

会修补它……但突然间这个想法似乎非常脆弱。有趣的思想实验。似乎应该有一种“正确”的方法来使用append()/list理解来做到这一点。

思考

您可以使用del或pop根据索引从列表中删除元素。Pop将打印它从列表中删除的成员,而列表删除该成员而不打印它。

>>> a=[1,2,3,4,5]>>> del a[1]>>> a[1, 3, 4, 5]>>> a.pop(1)3>>> a[1, 4, 5]>>>

这听起来不像你在使用列表列表,所以我会保持简短。你想使用pop,因为它会删除元素而不是列表元素,你应该使用del。要在python中调用最后一个元素,它是“-1”

>>> test = ['item1', 'item2']>>> test.pop(-1)'item2'>>> test['item1']

您可以搜索要删除的项目。这真的很简单。示例:

    letters = ["a", "b", "c", "d", "e"]letters.remove(letters[1])print(*letters) # Used with a * to make it unpack you don't have to (Python 3.x or newer)

产出:a、c、d、e

使用以下代码从列表中删除元素:

list = [1, 2, 3, 4]list.remove(1)print(list)
output = [2, 3, 4]

如果要从列表中删除索引元素数据,请使用:

list = [1, 2, 3, 4]list.remove(list[2])print(list)output : [1, 2, 4]

使用#0语句:

del listName[-N]

例如,如果您想删除最后3项,您的代码应该是:

del listName[-3:]

例如,如果您想删除最后8项,您的代码应该是:

del listName[-8:]

这取决于你想做什么。

如果你想返回你删除的元素,使用pop()

>>> l = [1, 2, 3, 4, 5]>>> l.pop(2)3>>> l[1, 2, 4, 5]

但是,如果您只想删除一个元素,请使用del

>>> l = [1, 2, 3, 4, 5]>>> del l[2]>>> l[1, 2, 4, 5]

此外,del允许您使用切片(例如del[2:])。

l-值列表;我们必须从inds2rem列表中删除索引。

l = range(20)inds2rem = [2,5,1,7]map(lambda x: l.pop(x), sorted(inds2rem, key = lambda x:-x))
>>> l[0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

还有一种按索引从列表中删除元素的方法。

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# remove the element at index 3a[3:4] = []# a is now [0, 1, 2, 4, 5, 6, 7, 8, 9]
# remove the elements from index 3 to index 6a[3:7] = []# a is now [0, 1, 2, 7, 8, 9]

a[x: y]指向索引xy-1中的元素。当我们将列表的该部分声明为空列表([])时,这些元素将被删除。

如果要删除列表中特定位置的元素,例如第2、第3和第7个元素,则不能使用

del my_list[2]del my_list[3]del my_list[7]

由于在删除第二个元素后,您删除的第三个元素实际上是原始列表中的第四个元素。您可以过滤原始列表中的第二、第三和第七个元素并获得一个新列表,如下所示:

new_list = [j for i, j in enumerate(my_list) if i not in [2, 3, 7]]

或者如果要删除多个索引:

print([v for i,v in enumerate(your_list) if i not in list_of_unwanted_indexes])

当然,也可以这样做:

print([v for i,v in enumerate(your_list) if i != unwanted_index])

已经提到了如何从列表中删除单个元素以及不同方法的优势。然而,请注意,删除多个元素有一些潜在的错误:

>>> l = [0,1,2,3,4,5,6,7,8,9]>>> indices=[3,7]>>> for i in indices:...     del l[i]...>>> l[0, 1, 2, 4, 5, 6, 7, 9]

原始列表的元素3和8(不是3和7)已被删除(因为列表在循环期间缩短了),这可能不是我们的意图。如果你想安全地删除多个索引,你应该首先删除索引最高的元素,例如:

>>> l = [0,1,2,3,4,5,6,7,8,9]>>> indices=[3,7]>>> for i in sorted(indices, reverse=True):...     del l[i]...>>> l[0, 1, 2, 4, 5, 6, 8, 9]