Скажем, у меня есть этот список здесь:
list = [a, b, c, d, e, f, g]
Как я могу удалить индексы 2, 3, 4
и 5
в то же время?
pop не принимает несколько значений. Как еще я это сделаю?
Скажем, у меня есть этот список здесь:
list = [a, b, c, d, e, f, g]
Как я могу удалить индексы 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]
Обратите внимание, что вам нужно удалить их в обратном порядке, чтобы не отбрасывать последующие индексы.
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]
Если они смежны, вы можете просто сделать
x[2:6] = []
Если вы хотите удалить несмежные индексы, это немного сложнее.
x = [v for i,v in enumerate(x) if i not in frozenset((2,3,4,5))]
lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
lst = lst[0:2] + lst[6:]
Это одношаговая операция. Он не использует цикл и поэтому выполняется быстро. Он использует сортировку списка.
Если вы можете использовать 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
, поэтому вам нужно назначить ему.
Не было большого намека на производительность для разных способов, поэтому я выполнил тест по удалению 5000 элементов из 50000 во всех трех общих подходах, и для меня был победитель numpy (если у вас есть элементы, которые вписываются в numpy)
Здесь код, который я запрограммировал (в третьем преобразовании функции из/в список можно удалить, если работа с массивами 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, l))
l = range(50000)
random.shuffle(l)
remove_id = random.sample(range(len(l)), 5000) # 10% ==> 5000
# ...
Старый вопрос, но у меня есть ответ.
Сначала рассмотрите элементы списка следующим образом:
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: a
1: b
2: c
3: d
4: charles
...
В [77]: multipop (mylist, [0, 2, 4])
Out [77]: ['charles', 'c', 'a']
...
В [78]: mylist
Out [78]: ['b', 'd']
другой вариант (на месте, любая комбинация индексов):
_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]