Это продолжение аналогичного question, в котором прозвучал лучший способ написать
for item in somelist:
if determine(item):
code_to_remove_item
и, похоже, консенсус был о чем-то вроде
somelist[:] = [x for x in somelist if not determine(x)]
Однако, я думаю, что если вы удаляете только несколько элементов, большинство элементов копируются в один и тот же объект, и, возможно, это медленно. В ответе к другому связанному question кто-то предлагает:
for item in reversed(somelist):
if determine(item):
somelist.remove(item)
Однако здесь list.remove
будет искать элемент, который является O (N) в длине списка. Может быть, мы ограничены тем, что список представлен как массив, а не связанный список, поэтому для удаления элементов необходимо будет переместить все после него. Тем не менее, предлагается здесь, что collection.dequeue представляется как дважды связанный список. Затем его можно удалить в O (1) при повторении. Как мы могли бы это сделать?
Обновление: Я тоже некоторое время тестировал, со следующим кодом:
import timeit
setup = """
import random
random.seed(1)
b = [(random.random(),random.random()) for i in xrange(1000)]
c = []
def tokeep(x):
return (x[1]>.45) and (x[1]<.5)
"""
listcomp = """
c[:] = [x for x in b if tokeep(x)]
"""
filt = """
c = filter(tokeep, b)
"""
print "list comp = ", timeit.timeit(listcomp,setup, number = 10000)
print "filtering = ", timeit.timeit(filt,setup, number = 10000)
и получил:
list comp = 4.01255393028
filtering = 3.59962391853