English 中文(简体)
如何通过索引从列表中移除元素
原标题:
  • 时间:2009-03-09 18:16:11
  •  标签:

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

我找到了list.remove(),但它通过逐一扫描列表上的项目来按值移除项目,速度较慢。

最佳回答

使用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]

这里是教程中的章节。Here

问题回答

你可能想要 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 ]

就像其他人提到的一样,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。旧列表对象因此被取消引用并被垃圾回收(前提是原始列表对象没有被其他变量引用)。

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

感谢 @MarkDickinson 指出这一点...

这个 Stack Overflow 回答解释了切片的概念。

请注意,此方法仅适用于正索引。

在使用对象时,__getitem__方法必须被定义,更重要的是定义了__add__方法,以返回包含两个操作数的项目的对象。

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

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 )

这适用于定义了__getitem____add__方法的list

三种方法的效率比较:

假设以下内容预定义:

a = range(10)
index = 3

<强>The del object[index] 方法:

到目前为止最有效的方法。它适用于所有定义了__del__方法的对象。

拆卸过程如下:

代码

def del_method():
    global a
    global index
    del a[index]

分解

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

pop方法:

它比 del 方法效率低,并且用于需要获取已删除项的情况。

代码

def pop_method():
    global a
    global index
    a.pop(index)

分解

 17     0 LOAD_GLOBAL     0 (a)
        3 LOAD_ATTR       1 (pop)
        6 LOAD_GLOBAL     2 (index)
        9 CALL_FUNCTION   1
       12 POP_TOP
       13 LOAD_CONST      0 (None)
       16 RETURN_VALUE

切片加法方法。

最不高效的。

代码

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

分解

 24     0 LOAD_GLOBAL    0 (a)
        3 LOAD_GLOBAL    1 (index)
        6 SLICE+2
        7 LOAD_GLOBAL    0 (a)
       10 LOAD_GLOBAL    1 (index)
       13 LOAD_CONST     1 (1)
       16 BINARY_ADD
       17 SLICE+1
       18 BINARY_ADD
       19 STORE_GLOBAL   0 (a)
       22 LOAD_CONST     0 (None)
       25 RETURN_VALUE
None

注意:在所有三个分解中忽略最后两行,这基本上是return None。此外,前两行正在加载全局值aindex

如果您想在列表中移除特定位置的元素,例如第2、3和7个元素,您无法使用

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

由于您删除了第二个元素,您实际删除的第三个元素是原始列表中的第四个元素。 您可以在原始列表中筛选第2、3和7个元素,并获得一个新列表,如下所示:

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

pop 也很有用,可以从列表中删除并保留一个项目。其中 del 实际上是将项目删掉。

>>> x = [1, 2, 3, 4]

>>> p = x.pop(1)
>>> p
    2

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

>>> 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]

使用 del 语句:

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:])。

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

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

另一种通过索引从列表中删除元素的方法。

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

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

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

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

You could just search for the item you want to delete. It is really simple. Example:

    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]

正如先前提到的,最佳实践是使用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 ]

嗯...无法在负索引值上工作,将考虑并更新。

我想。

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

会修补它...但突然感觉这个想法非常脆弱。有趣的思想实验。看起来应该有一种适当的方式可以用append() /列表推导来完成。

沉思

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]

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

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

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

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])

您可以使用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]
>>> 

人们可以使用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]




相关问题
热门标签