有没有可能同时从列表中删除多个元素?如果我想删除索引为0和2的元素,并尝试类似于del somelist [0]
然后跟着del somelist [2]
,第二条语句实际上会删除somelist[3]
。
我猜我可以总是先删除较高编号的元素,但我希望有更好的方法。
这里还有另一种方法可以原地删除元素。而且如果你的列表非常长,使用这种方法更快。
>>> a = range(10)
>>> remove = [0,4,5]
>>> from collections import deque
>>> deque((list.pop(a, i) for i in sorted(remove, reverse=True)), maxlen=0)
>>> timeit.timeit('[i for j, i in enumerate(a) if j not in remove]', setup='import random;remove=[random.randrange(100000) for i in range(100)]; a = range(100000)', number=1)
0.1704120635986328
>>> timeit.timeit('deque((list.pop(a, i) for i in sorted(remove, reverse=True)), maxlen=0)', setup='from collections import deque;import random;remove=[random.randrange(100000) for i in range(100)]; a = range(100000)', number=1)
0.004853963851928711
l = ['a','b','a','c','a','d']
to_remove = [1, 3]
[l[i] for i in range(0, len(l)) if i not in to_remove])
实际上这与得票最高的答案基本相同,只是写法不同。请注意,使用 l.index() 不是个好主意,因为它无法处理列表中的重复元素。
虽然这个问题已经被提到过,但似乎没有人成功将其解决。
一个 O(n)
的解决方案是:
indices = {0, 2}
somelist = [i for j, i in enumerate(somelist) if j not in indices]
这与SilentGhost版本非常接近,但添加了两个花括号。
log(len(indices))
的查找操作,那么这就不是 O(n)
。 - Mad Physicistj not in indices
是 O(1)
。 - Veedracj not in indices
仍需要查找,这是O(log(len(indices)))
。虽然我同意在2元素集合中的查找符合O(1)
,但在一般情况下它将是O(log(N))
。无论哪种方式,O(N log(N))
仍然优于O(N^2)
。 - Mad Physicistj not in indices
是O(1)的,说真的。" - Veedrac总结来自@sth的评论。任何实现了abc.MutableSequence接口的类,特别是list
,都可以通过__delitem__
魔术方法删除项目。该方法与__getitem__
类似,意味着它可以接受整数或切片。以下是一个例子:
class MyList(list):
def __delitem__(self, item):
if isinstance(item, slice):
for i in range(*item.indices(len(self))):
self[i] = 'null'
else:
self[item] = 'null'
l = MyList(range(10))
print(l)
del l[5:8]
print(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 'null', 'null', 'null', 8, 9]
从技术角度来说,不能同时删除两个对象。但是,通过一行简洁优美的Python代码,可以同时删除两个对象。
del (foo['bar'],foo['baz'])
将递归删除foo['bar']
,然后删除foo['baz']
另一种实现从最高索引处删除的方法。
for i in range(len(yourlist)-1, -1, -1):
del yourlist(i)
my_list = ['word','yes','no','nice']
c=[b for i,b in enumerate(my_list) if not i in (0,2,3)]
print c
mylist=[66.25, 333, 1, 4, 6, 7, 8, 56, 8769, 65]
indexes = 4,6
indexes = sorted(indexes, reverse=True)
for i in index:
mylist.pop(i)
print mylist
对于列表A中的索引0和2:
for x in (2,0): listA.pop(x)
需要从listA中随机删除一些索引:
indices=(5,3,2,7,0)
for x in sorted(indices)[::-1]: listA.pop(x)
remove方法会导致列表元素大量移动,我认为最好制作一个副本:
...
new_list = []
for el in obj.my_list:
if condition_is_true(el):
new_list.append(el)
del obj.my_list
obj.my_list = new_list
...