179

假设我在这里有这个列表:

list = [a, b, c, d, e, f, g]

我将如何同时删除说2, 3, 4索引5

pop 不接受多个值。我该怎么做?

4

8 回答 8

337

您需要在循环中执行此操作,没有内置操作可以一次删除多个索引。

您的示例实际上是一个连续的索引序列,因此您可以这样做:

del my_list[2:6]

这将删除从 2 开始并在 6 之前结束的切片。

从您的问题中不清楚您是否需要删除任意索引集合,或者它是否始终是一个连续的序列。

如果您有任意索引集合,则:

indexes = [2, 3, 5]
for index in sorted(indexes, reverse=True):
    del my_list[index]

请注意,您需要以相反的顺序删除它们,以免丢失后续索引。

于 2012-07-03T01:08:08.347 回答
59
remove_indices = [1,2,3]
somelist = [i for j, i in enumerate(somelist) if j not in remove_indices]

例子:

In [9]: remove_indices = [1,2,3]

In [10]: somelist = range(10)

In [11]: somelist = [i for j, i in enumerate(somelist) if j not in remove_indices]

In [12]: somelist
Out[12]: [0, 4, 5, 6, 7, 8, 9]
于 2012-07-03T01:09:11.980 回答
31

对于不同方式的性能没有太多提示,所以我进行了一个测试,在所有 3 种通常不同的方法中从 50000 中删除 5000 项,对我来说 numpy 是赢家(如果你有适合 numpy 的元素):

  • 枚举列表理解需要 7.5 秒 [另一台 PC 上为 4.5 秒]
  • 0.08 秒以相反的顺序删除项目 [0.017 (!) 秒]
  • numpy.delete 为 0.009 秒 [0.006 秒]

这是我计时的代码(如果可以直接在 numpy 数组上工作,则可以删除从/到列表的第三个函数转换):

import time
import numpy as np
import random

def del_list_indexes(l, id_to_del):
    somelist = [i for j, i in enumerate(l) if j not in id_to_del]
    return somelist

def del_list_inplace(l, id_to_del):
    for i in sorted(id_to_del, reverse=True):
        del(l[i])

def del_list_numpy(l, id_to_del):
    arr = np.array(l, dtype='int32')
    return list(np.delete(arr, id_to_del))

l = range(50000)
random.shuffle(l)
remove_id = random.sample(range(len(l)), 5000) # 10% ==> 5000

# ...
于 2016-12-10T20:09:49.573 回答
16

如果您可以使用numpy,那么您可以删除多个索引:

>>> import numpy as np
>>> a = np.arange(10)
>>> np.delete(a,(1,3,5))
array([0, 2, 4, 6, 7, 8, 9])

如果您使用np.r_,您可以将切片与单个索引结合起来:

>>> np.delete(a,(np.r_[0:5,7,9]))
array([5, 6, 8])

但是,删除不是in place,因此您必须分配给它。

于 2012-07-03T09:22:45.410 回答
15

如果它们是连续的,你可以这样做

x[2:6] = []

如果要删除不连续的索引,那就有点棘手了。

x = [v for i,v in enumerate(x) if i not in frozenset((2,3,4,5))] 
于 2012-07-03T01:08:21.570 回答
5
lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
lst = lst[0:2] + lst[6:]

这是一个单步操作。它不使用循环,因此执行速度很快。它使用列表切片。

于 2016-12-12T09:34:50.173 回答
1

另一种选择(到位,指数的任何组合):

_marker = object()

for i in indices:
    my_list[i] = _marker  # marked for deletion

obj[:] = [v for v in my_list if v is not _marker]
于 2017-07-02T14:16:07.630 回答
0

老问题,但我有一个答案。

首先,仔细阅读列表中的元素,如下所示:

for x in range(len(yourlist)):
    print '%s: %s' % (x, yourlist[x])

然后,使用要弹出的元素的索引列表调用此函数。它足够强大,列表的顺序无关紧要。

def multipop(yourlist, itemstopop):
    result = []
    itemstopop.sort()
    itemstopop = itemstopop[::-1]
    for x in itemstopop:
        result.append(yourlist.pop(x))
    return result

作为奖励,结果应该只包含您想要删除的元素。

在 [73] 中:mylist = ['a','b','c','d','charles']

在 [76] 中:对于范围内的 x(len(mylist)):

      mylist[x])

.....:

0:一个

1:乙

2:c

3:d

4:查尔斯

...

在 [77] 中:multipop(mylist, [0, 2, 4])

出[77]:['查尔斯','c','a']

...

在 [78] 中:我的列表

出[78]:['b','d']

于 2016-07-07T19:48:25.430 回答