2014-01-09 3 views
3

У меня есть список например.Удаление нескольких индексов из списка за один раз - python

lst = [2, 5, 7, 12, 13] 


lst.pop(3) #12 
lst.pop(4) #13 

Поскольку lst [3] удален, lst [4] больше не существует (вне допустимого диапазона). Это дает мне ошибку. Теперь я знаю, что вы могли бы сказать, изменить свой код так: ...

lst.pop(4) #13 
lst.pop(3) #12 

... и это плохо исправить ошибку, но моя проблема заключается в моем фактическом коде «выскакивает» случайных чисел, поэтому она должна быть все это сделано одновременно, чтобы избежать ошибок.

Есть ли способ «выскакивает» в то же время ... как-то похожее на это:?

lst.pop(3, 4) #12 and 13 at once 

Спасибо за любые ответы.

+0

Не используйте 'list' как имя переменной; вы маскируете встроенный тип. –

+1

Возможный дубликат [Как удалить сразу несколько индексов из списка?] (Http: // stackoverflow.com/questions/11303225/how-to-remove-multiple-indexes-from-a-list-at-same-time) –

ответ

11

Вы можете использовать список понимание для восстановления списка:

indices = {3, 4} 
newlist = [v for i, v in enumerate(oldlist) if i not in indices] 

Я использовал набор для индексов здесь, поскольку тестирование членства набора быстрее, чем со списком.

Обратите внимание, что удаление (лучше всего сделано с del lst[index]) частично перестраивает список; делать это с одним циклом в понимании списка может быть более эффективным.

Демо:

>>> oldlist = [2, 5, 7, 12, 13] 
>>> indices = {3, 4} 
>>> [v for i, v in enumerate(oldlist) if i not in indices] 
[2, 5, 7] 
+0

Как это делается с моим примером? –

+0

@ DennisCallanan: именно так, как я писал; Я также дал вам быструю демонстрационную сессию. –

+0

Спасибо, мельница! Любопытно, если бы у меня была программа, выполняющая это в цикле много раз в секунду. Будет ли этот метод намного медленнее, чем просто «выскочить» два числа из списка? –

3

Вы можете удалить их с список понимание, что позволит создать новый список:

>>> lst = [2, 5, 7, 12, 13] 
>>> [v for i, v in enumerate(lst) if i not in {4,3}] 
[2, 5, 7] 

Вы просто должны назначить этот новый список lst снова.

0

Для этого можно использовать индексирование numpy.

0

Если вы действительно хотите сделать это путем удаления на месте, очевидный ответ сортировать индексы удалить:

>>> lst = [2, 5, 7, 12, 13] 
>>> indices = {3, 4} 
>>> for index in sorted(indices, reverse=True): 
...  del lst[index] 
>>> print(lst) 
[2, 5, 7] 

Однако, обратите внимание, что это в два раза больше кода в списке Мартейн в понимание. И если вы пытаетесь сделать это так, как оптимизацию, (а) это почти наверняка преждевременная оптимизация, и (б) это скорее всего пессимизация.

Если вы делаете это потому, что какой-либо другой код содержит ссылку на lst, и вам это нужно, чтобы увидеть изменения, вы можете использовать список понимание, вместе с присвоением ломтика:

>>> lst[:] = [v for i, v in enumerate(lst) if i not in indices] 

Здесь , мы создаем новый список, а затем заменяем подстилку, представляющую все содержимое lst, с этим новым списком.

0
lst = [2, 5, 7, 12, 13] 

indexes = [3, 4] 
to_del = object() 

for index in indexes: 
    lst[index] = to_del 

for _ in indexes: 
    lst.remove(to_del) 

print(lst) 

[2, 5, 7] 
+2

Если вам нужен безопасный дозор, вы всегда можете использовать 'to_del = object()'. Результат никогда не сравним (или хеш), равный любому объекту, кроме самого себя. – abarnert

+0

@abarnert Спасибо +. –