Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何同时从列表中删除多个索引?_Python_List - Fatal编程技术网

Python 如何同时从列表中删除多个索引?

Python 如何同时从列表中删除多个索引?,python,list,Python,List,假设我在这里有这个列表: list = [a, b, c, d, e, f, g] 如何同时删除say索引2、3、4和5 pop不接受多个值。否则我怎么做呢?您需要在循环中执行此操作,没有内置操作可以一次删除多个索引 您的示例实际上是一个连续的索引序列,因此您可以执行以下操作: del my_list[2:6] 这将删除从2开始并在6之前结束的切片 从您的问题中不清楚您是否需要删除任意索引集合,或者它是否始终是一个连续序列 如果有任意索引集合,则: indexes = [2, 3, 5] f

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

list = [a, b, c, d, e, f, g]
如何同时删除say索引
2、3、4
5


pop不接受多个值。否则我怎么做呢?

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

您的示例实际上是一个连续的索引序列,因此您可以执行以下操作:

del my_list[2:6]
这将删除从2开始并在6之前结束的切片

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

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

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

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

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

x[2:6] = []
如果您想删除非连续索引,则需要稍微复杂一些

x = [v for i,v in enumerate(x) if i not in frozenset((2,3,4,5))] 
例如:

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]
如果可以使用,则可以删除多个索引:

>>> import numpy as np
>>> a = np.arange(10)
>>> np.delete(a,(1,3,5))
array([0, 2, 4, 6, 7, 8, 9])
如果您使用
np.r\uu
,您可以将切片与单个索引相结合:

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

但是,删除未到位,因此您必须分配给它。

旧问题,但我有一个答案

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

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

0:a

1:b

2:c

3:d

4:查尔斯

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

Out[77]:['charles','c','a']

在[78]中:mylist

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


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

  • 7.5秒用于枚举列表理解[4.5秒用于另一台PC]
  • 按相反顺序删除项目的时间为0.08秒[0.017(!)秒]
  • numpy为0.009秒。删除[0.006秒]
下面是我计时的代码(在第三个函数中,如果直接在numpy数组上工作是可以的,则可以删除从/到列表的转换):

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

另一个选项(就地,任何索引组合):


值得注意的是,您必须使用枚举来执行此操作的原因是,您不能删除正在迭代的内容,这将是不好的。@从技术上讲,只有在使用真正的迭代器时才是这样。如果您使用一个简单的int来保持您在列表中的位置,则没有问题,除了如果您删除低于当前位置的内容,索引将跳过。是的,这可能会跳出边界,通常不是一件好事。+1如果不是
del my_list[index],这会有什么不同
我们使用了
我的列表.pop(索引)
?这有关系吗?在效率或语义方面?请原谅我的评论,我正在学习Python,但是Python在循环删除时重新索引数组?为什么按正常顺序循环会引发未定义的偏移量异常?@kitensei它会重新索引,但因为先按相反顺序对索引排序,所以我们会从列表的右端删除,所以在删除元素之前,我们永远不会重新索引。向后循环索引。天才!我在这里幻想了一个荒谬的情况,在我前进的过程中,指数递减,而这是如此的优雅@Levon我认为主要的区别在于你移除了。因为我们不需要删除的值,所以在这种情况下我们可能应该使用
del
,尽管两者都可以。您应该包括对代码的解释。一般来说,描述某些命令或代码解决问题的方式和原因更为有用,因为它有助于OP和其他人解决类似问题。请查看版本并进行指导。想知道为什么1460天和23410视图没有提出此简单解决方案。这有点令人沮丧。我编辑了您的答案以改进语法,并使用
lst
作为变量名,因为
list
是Python数据类型。没有人建议将此作为解决方案的原因是,这将创建一个新的列表对象(基于原始列表的内容),而不是实际修改原始列表对象。由于最终结果是相似的,我将投票支持你的答案。欢迎来到。什么是[6:]做的?
del\u list\u index
如果您先将
id\u to\u del
转换为一个集合,应该会快得多。@C.Yduqoli如果使用
集合
进行
枚举
的次数是:
枚举
=0.0041,
del
=0.035,
numpy
=0.0079,正如@C.Yduqoli在下面指出的那样,这是最有效的解决方案(我们不需要继续重建列表),但您必须先将
删除索引
转换为
def multipop(yourlist, itemstopop):
    result = []
    itemstopop.sort()
    itemstopop = itemstopop[::-1]
    for x in itemstopop:
        result.append(yourlist.pop(x))
    return result
      mylist[x])
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

# ...
lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
lst = lst[0:2] + lst[6:]
_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]