Удаление нескольких элементов из списка

Можно ли удалить несколько элементов из списка одновременно? Если я хочу удалить элементы с индексами 0 и 2 и попробовать что-то вроде del somelist[0], за которым следует del somelist[2], второй оператор фактически удалит somelist[3].

Полагаю, я всегда могу сначала удалить элементы с более высокими номерами, но я надеюсь, что есть способ получше.


person Community    schedule 30.01.2009    source источник
comment
Используйте несколько срезов, если вы заботитесь об эффективности.   -  person tejasvi88    schedule 18.08.2020


Ответы (30)


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

indices = 0, 2
somelist = [i for j, i in enumerate(somelist) if j not in indices]
person SilentGhost    schedule 30.01.2009
comment
Почти, только если удалить весь список. это будет len (индексы) * len (somelist). Он также создает копию, которая может или не может быть желательной. - person Richard Levasseur; 31.01.2009
comment
если вы проверяете значение в списке, это так. оператор in работает со значениями списка, тогда как он работает с ключами dict. Если я ошибаюсь, укажите мне ссылку / ссылку - person Richard Levasseur; 31.01.2009
comment
Причина, по которой я выбрал кортеж для индексов, заключалась только в простоте записи. было бы идеально, если бы set () давал O (n) - person SilentGhost; 31.01.2009
comment
Это вовсе не удаление элементов из некоторого списка, а создание нового списка. Если что-то содержит ссылку на исходный список, все элементы в нем все равно будут. - person Tom Future; 31.07.2011
comment
@SilentGhost Изначально я избегал использования этого решения, потому что j не в индексах звучал медленно, когда много индексов. Как вы признаете, set () исправит это. Удивлен, что вы не редактировали свой пост. Итак, исправление производительности заключается в замене in indices на in set(indices)? - person ToolmakerSteve; 15.12.2013
comment
@TomFuture. Истинный. При создании метода для выполнения задачи рекомендуется создавать новый объект, а не изменять оригинал. Предоставьте пользователю возможность изменять оригинал, если это необходимо. Сделайте это с [:]. Например. somelist[:] = ... заменит элементы объекта, на который указывает somelist, влияя на все ссылки на этот объект. - person ToolmakerSteve; 15.12.2013
comment
@SilentGhost Нет необходимости в перечислении. Как насчет этого: somelist = [ lst[i] for i in xrange(len(lst)) if i not in set(indices) ]? - person ToolmakerSteve; 15.12.2013
comment
(Я добавил ответ намного ниже, который показывает это в действии.) - person ToolmakerSteve; 15.12.2013
comment
Передумал. Придавая результатам перечисления более наглядные имена, этот подход легко читается. Мне также помогает, если добавляются паренсы. То есть: [ value for (i, value) in enumerate(lst) if i not in set(indices) ]. - person ToolmakerSteve; 15.12.2013
comment
Блестяще! этот метод действительно помогает мне - person Aditya Kresna Permana; 20.09.2015
comment
Мне больше нравится, когда index = {0, 2} делает индексы набором с самого начала :) - person amohr; 08.02.2017
comment
Как говорили другие, это НЕ удаляет ничего из списка - он создает новый список с исключенными элементами. Для некоторых приложений оба способа подходят, но OP специально упоминает удаление и del. - person Arru; 22.02.2019

Почему-то мне здесь не нравится ни один из ответов. Да, они работают, но, строго говоря, большинство из них не удаляют элементы в списке, не так ли? (Но сделать копию и затем заменить оригинал отредактированной копией).

Почему бы просто не удалить сначала более высокий индекс?

Есть причина для этого? Я бы просто сделал:

for i in sorted(indices, reverse=True):
    del somelist[i]

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

Я что-то упустил? Есть ли причина НЕ удалять в обратном порядке?

person tglaria    schedule 24.02.2015
comment
Есть две причины. (a) Для списка временная сложность будет выше, чем у метода создания копии (с использованием набора индексов) в среднем (при условии случайных индексов), потому что некоторые элементы необходимо сдвинуть вперед несколько раз. (б) По крайней мере, для меня это трудно читать, потому что есть функция сортировки, которая не соответствует какой-либо реальной логике программы и существует исключительно по техническим причинам. Несмотря на то, что к настоящему времени я уже полностью понимаю логику, я все же чувствую, что ее будет трудно читать. - person Imperishable Night; 27.10.2018
comment
@ImperishableNight не могли бы вы уточнить (а)? Я не понимаю, что нужно изменить некоторые элементы. Для (б) вы можете просто определить функцию, если вам нужна ясность чтения. - person tglaria; 29.10.2018
comment
Стоит отметить, что вы также можете использовать somelist.pop(i) вместо del, если хотите что-то сделать с удаляемым элементом. - person user5359531; 14.09.2020
comment
@tglaria Списки занимают непрерывный объем памяти; поэтому, если вы удалите любой элемент, кроме последнего, элементы справа должны быть сдвинуты влево. (Я использую 'left' в качестве начала списка и 'right' в качестве конца списка здесь) - person luizfls; 10.04.2021
comment
@luizfls, это интересно. Интересно, нужны ли для этого какие-то ресурсы. Не было бы проще переместить адрес к следующему элементу списка вместо того, чтобы перемещать элементы списка? - person tglaria; 15.06.2021
comment
@tglaria Это возможно, и именно так реализованы связанные списки. Вы теряете аспект непрерывности (единичный блок) списка Python, который дает вам произвольный доступ, то есть возможность доступа к любому элементу в постоянное время. В связанных списках элементы разбросаны по памяти, и вы сохраняете адреса, указывающие на следующий элемент. С другой стороны, как вы предложили, нет необходимости сдвигать элементы после удаления. Так что это вопрос компромисса. - person luizfls; 16.06.2021

Если вы удаляете несколько несмежных элементов, то то, что вы описываете, является лучшим способом (и да, обязательно начинайте с самого высокого индекса).

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

a[2:10] = []
person Greg Hewgill    schedule 30.01.2009
comment
Вы также можете сказать del a[2:10] с тем же эффектом. - person sth; 31.01.2009
comment
@sth Интересно, что del немного быстрее, чем присваивание. - person thefourtheye; 18.11.2013

Вы можете использовать numpy.delete следующим образом:

import numpy as np
a = ['a', 'l', 3.14, 42, 'u']
I = [0, 2]
np.delete(a, I).tolist()
# Returns: ['l', '42', 'u']

Если вы не возражаете, чтобы в конце был массив numpy, вы можете не указывать .tolist(). Вы также должны увидеть несколько довольно значительных улучшений скорости, что сделает это решение более масштабируемым. Я не тестировал его, но numpy операции представляют собой скомпилированный код, написанный либо на C, либо на Fortran.

person philE    schedule 23.09.2015
comment
общее решение, когда элементы не идут подряд +1 - person noɥʇʎԀʎzɐɹƆ; 24.06.2016
comment
вопрос здесь, как насчет удаления ['a', 42]. - person evanhutomo; 22.11.2017
comment
ОГРОМНЫЕ бонусные баллы за это решение по сравнению с другими за скорость. Что я могу сказать, так это то, что для очень большого набора данных мне потребовалось несколько минут, чтобы достичь чего-то, что заняло всего несколько секунд с добрым старым numpy. - person legel; 22.02.2020

В качестве специализации ответа Грега вы даже можете использовать расширенный синтаксис среза. например. Если вы хотите удалить элементы 0 и 2:

>>> a= [0, 1, 2, 3, 4]
>>> del a[0:3:2]
>>> a
[1, 3, 4]

Конечно, это не касается произвольного выбора, но, безусловно, может работать для удаления любых двух элементов.

person bobince    schedule 01.02.2009

Как функция:

def multi_delete(list_, *args):
    indexes = sorted(list(args), reverse=True)
    for index in indexes:
        del list_[index]
    return list_

Выполняется за время n log (n), что должно сделать его наиболее быстрым правильным решением.

person Nikhil Chelliah    schedule 30.01.2009
comment
Версия с args.sort (). Reverse () определенно лучше. Также случается работать с dicts вместо того, чтобы бросать или, что еще хуже, незаметно искажать. - person ; 31.01.2009
comment
sort () не определен для кортежа, вам сначала нужно преобразовать его в список. sort () возвращает None, поэтому вы не можете использовать для него reverse (). - person SilentGhost; 31.01.2009
comment
@ R. Pate: По этой причине я удалил первую версию. Спасибо. @ SilentGhost: Исправлено. - person Nikhil Chelliah; 31.01.2009
comment
@Nikhil: нет, вы этого не сделали;) args = list (args) args.sort () args.reverse () но лучшим вариантом будет: args = sorted (args, reverse = True) - person SilentGhost; 31.01.2009
comment
О, я понимаю, что вы имели в виду - вы не можете связать методы, что кажется глупым, даже для неизменяемых объектов. Мне не нравится изменять тип переменной, как в args = list (args). Я знаю, что это сделано, но это может сбивать с толку. - person Nikhil Chelliah; 31.01.2009
comment
Аргумент списка переопределяет встроенный список, используемый внутри метода. - person iny; 31.01.2009
comment
Да, я бы дал этому решению +1, если бы оно действительно работало так, как написано (ср. Что сказал @iny). - person Carl Meyer; 31.01.2009
comment
почему вы сделали list(args), не могли бы вы использовать args как есть? - person João Portela; 12.10.2010
comment
@ JoãoPortela прав. После первого редактирования, которое поместило list(args) внутрь sorted(), оболочка list() больше не нужна, согласно ответному комментарию SilentGhost. Протестировано и подтверждено с вводом кортежа. Отправили как редактирование. - person ToolmakerSteve; 15.12.2013
comment
n log n? Действительно? Я не думаю, что del list[index] - это O (1). - person user202729; 15.06.2018

Итак, вы по сути хотите удалить несколько элементов за один проход? В этом случае позиция следующего удаляемого элемента будет смещена в зависимости от того, сколько элементов было удалено ранее.

Наша цель - удалить все гласные, которые предварительно вычисляются как индексы 1, 4 и 7. Обратите внимание, что важно, чтобы индексы to_delete располагались в возрастающем порядке, иначе это не сработает.

to_delete = [1, 4, 7]
target = list("hello world")
for offset, index in enumerate(to_delete):
  index -= offset
  del target[index]

Было бы сложнее удалить элементы в любом порядке. ИМО, сортировка to_delete может быть проще, чем выяснение, когда вы должны или не должны вычитать из index.

person Community    schedule 31.01.2009

Я новичок в Python, и мое программирование на данный момент грубое и грязное, если не сказать больше, но моим решением было использовать комбинацию базовых команд, которые я изучил в ранних руководствах:

some_list = [1,2,3,4,5,6,7,8,10]
rem = [0,5,7]

for i in rem:
    some_list[i] = '!' # mark for deletion

for i in range(0, some_list.count('!')):
    some_list.remove('!') # remove
print some_list

Очевидно, что из-за необходимости выбора символа «пометки для удаления» у этого есть свои ограничения.

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

person Paul    schedule 13.09.2012
comment
Вместо того, чтобы использовать '!' в качестве специального символа используйте «Нет». Это сохраняет каждый персонаж в силе и освобождает ваши возможности. - person benathon; 14.11.2015

Вот альтернатива, которая не использует enumerate () для создания кортежей (как в исходном ответе SilentGhost).

Мне это кажется более читаемым. (Возможно, я бы чувствовал себя иначе, если бы у меня была привычка использовать enumerate.) ПРЕДОСТЕРЕЖЕНИЕ: Я не тестировал производительность двух подходов.

# Returns a new list. "lst" is not modified.
def delete_by_indices(lst, indices):
    indices_as_set = set(indices)
    return [ lst[i] for i in xrange(len(lst)) if i not in indices_as_set ]

ПРИМЕЧАНИЕ. Синтаксис Python 2.7. Для Python 3 xrange => range.

Использование:

lst = [ 11*x for x in xrange(10) ]
somelist = delete_by_indices( lst, [0, 4, 5])

somelist:

[11, 22, 33, 66, 77, 88, 99]

--- БОНУС ---

Удалить несколько значений из списка. То есть у нас есть значения, которые мы хотим удалить:

# Returns a new list. "lst" is not modified.
def delete__by_values(lst, values):
    values_as_set = set(values)
    return [ x for x in lst if x not in values_as_set ]

Использование:

somelist = delete__by_values( lst, [0, 44, 55] )

somelist:

[11, 22, 33, 66, 77, 88, 99]

Это тот же ответ, что и раньше, но на этот раз мы предоставили ЗНАЧЕНИЯ, которые нужно удалить [0, 44, 55].

person ToolmakerSteve    schedule 14.12.2013
comment
Я решил, что @SilentGhost трудно читать только из-за неописательных имен переменных, используемых для результата перечисления. Кроме того, скобки облегчили бы чтение. Вот как я бы назвал его решение (с добавленным набором для повышения производительности): [ value for (i, value) in enumerate(lst) if i not in set(indices) ]. Но я оставлю свой ответ здесь, потому что я также покажу, как удалять по значениям. Это более простой случай, но может кому-то помочь. - person ToolmakerSteve; 15.12.2013
comment
@ Veedrac- спасибо; Я переписал, чтобы сначала собрать набор. Как вы думаете - теперь решение быстрее, чем у SilentGhost? (Я не считаю это достаточно важным, чтобы на самом деле рассчитать время, просто спросив ваше мнение.) Точно так же я бы переписал версию SilentGhost как indices_as_set = set(indices), [ value for (i, value) in enumerate(lst) if i not in indices_as_set ], чтобы ускорить ее. - person ToolmakerSteve; 07.11.2014
comment
Есть ли причина стиля для двойного подчеркивания в delete__by_values()? - person Tom; 25.05.2015

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

stuff = ['a', 'b', 'c', 'd', 'e', 'f', 'woof']
index = [0, 3, 6]
new = [i for i in stuff if stuff.index(i) not in index]

Это возвращает:

['b', 'c', 'e', 'f']
person Meow    schedule 06.12.2015
comment
хороший ответ, но наименование списка индексов как index вводит в заблуждение, поскольку в итераторе списка используется метод index() - person Joe; 18.06.2019

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

>>> 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
person user545424    schedule 10.08.2011
comment
+1: Интересное использование deque для выполнения действия for как части выражения, вместо того, чтобы требовать блок for .. :. Однако в этом простом случае я считаю Nikhil for block более читабельным. - person ToolmakerSteve; 15.12.2013

Об этом уже упоминалось, но почему-то никому не удалось это исправить.

На O(n) решение будет:

indices = {0, 2}
somelist = [i for j, i in enumerate(somelist) if j not in indices]

Это действительно близко к версии SilentGhost, но добавляет две фигурные скобки.

person Veedrac    schedule 28.09.2014
comment
Это не O(n), если вы подсчитываете поиски, которые занимают log(len(indices)) для каждой итерации. - person Mad Physicist; 20.10.2015
comment
@MadPhysicist j not in indices - это O(1). - person Veedrac; 21.10.2015
comment
Я не знаю, как вы получили этот номер. Поскольку индексы - это набор, j not in indices по-прежнему требует поиска, то есть O(log(len(indices))). Хотя я согласен с тем, что поиск в наборе из двух элементов квалифицируется как O(1), в общем случае это будет O(log(N)). В любом случае O(N log(N)) по-прежнему лучше O(N^2). - person Mad Physicist; 21.10.2015
comment
@MadPhysicist j not in indices это O(1), серьезно. - person Veedrac; 21.10.2015
comment
А что именно сделали две брекеты? - person Nuclear03020704; 15.06.2020

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 () - не лучшая идея, поскольку он не может обрабатывать повторяющиеся элементы в списке.

person zinc    schedule 13.07.2017

Метод 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
...
person luca    schedule 11.09.2014

Технически ответ - НЕТ, невозможно удалить два объекта ОДНОВРЕМЕННО. Однако можно удалить два объекта в одной строке красивого питона.

del (foo['bar'],foo['baz'])

повторно удалит foo['bar'], затем foo['baz']

person David Brilliant    schedule 17.06.2015
comment
Это удаляет из объекта dict, а не из списка, но я все еще добавляю ему +1, потому что это чертовски красиво! - person Ulf Aslak; 12.02.2016
comment
Это также относится к списку с соответствующим синтаксисом. Однако утверждение, что невозможно удалить два объекта одновременно, неверно; см. ответ @bobince - person Pedro Gimeno; 25.10.2019

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

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
person Gourav Singla    schedule 18.12.2015

Для индексов 0 и 2 из списка А:

for x in (2,0): listA.pop(x)

Для удаления некоторых случайных индексов из спискаA:

indices=(5,3,2,7,0) 
for x in sorted(indices)[::-1]: listA.pop(x)
person jam    schedule 08.05.2016

Я хотел найти способ сравнить различные решения, позволяющие легко поворачивать ручки.

Сначала я сгенерировал свои данные:

import random

N = 16 * 1024
x = range(N)
random.shuffle(x)
y = random.sample(range(N), N / 10)

Затем я определил свои функции:

def list_set(value_list, index_list):
    index_list = set(index_list)
    result = [value for index, value in enumerate(value_list) if index not in index_list]
    return result

def list_del(value_list, index_list):
    for index in sorted(index_list, reverse=True):
        del(value_list[index])

def list_pop(value_list, index_list):
    for index in sorted(index_list, reverse=True):
        value_list.pop(index)

Затем я использовал timeit для сравнения решений:

import timeit
from collections import OrderedDict

M = 1000
setup = 'from __main__ import x, y, list_set, list_del, list_pop'
statement_dict = OrderedDict([
    ('overhead',  'a = x[:]'),
    ('set', 'a = x[:]; list_set(a, y)'),
    ('del', 'a = x[:]; list_del(a, y)'),
    ('pop', 'a = x[:]; list_pop(a, y)'),
])

overhead = None
result_dict = OrderedDict()
for name, statement in statement_dict.iteritems():
    result = timeit.timeit(statement, number=M, setup=setup)
    if overhead is None:
        overhead = result
    else:
        result = result - overhead
        result_dict[name] = result

for name, result in result_dict.iteritems():
    print "%s = %7.3f" % (name, result)

Вывод

set =   1.711
del =   3.450
pop =   3.618

Итак, генератор с индексами в set оказался победителем. И del немного быстрее, чем pop.

person David Cullen    schedule 24.03.2017
comment
Спасибо за это сравнение, это побудило меня сделать свои собственные тесты (на самом деле просто заимствовал ваш код) и для небольшого количества элементов, которые нужно удалить, накладные расходы на создание SET делают его худшим решением (используйте 10, 100, 500 для длина y, и вы увидите). Как правило, это зависит от приложения. - person tglaria; 10.10.2017

Вы можете использовать эту логику:

my_list = ['word','yes','no','nice']

c=[b for i,b in enumerate(my_list) if not i in (0,2,3)]

print c
person raghu    schedule 16.11.2017

Еще одна реализация идеи удаления по наивысшему индексу.

for i in range(len(yourlist)-1, -1, -1):
    del yourlist(i)
person ipramusinto    schedule 19.09.2018

На самом деле я могу придумать два способа сделать это:

  1. нарежьте список как (это удаляет 1-й, 3-й и 8-й элементы)

    somelist = somelist [1: 2] + somelist [3: 7] + somelist [8:]

  2. сделайте это на месте, но по одному:

    somelist.pop (2) somelist.pop (0)

person Bartosz Radaczyński    schedule 30.01.2009

Вы можете сделать это по диктовке, а не по списку. В списке элементы расположены по порядку. В дикте они зависят только от индекса.

Простой код, чтобы объяснить это путем выполнения:

>>> lst = ['a','b','c']
>>> dct = {0: 'a', 1: 'b', 2:'c'}
>>> lst[0]
'a'
>>> dct[0]
'a'
>>> del lst[0]
>>> del dct[0]
>>> lst[0]
'b'
>>> dct[0]
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    dct[0]
KeyError: 0
>>> dct[1]
'b'
>>> lst[1]
'c'

Способ "преобразовать" список в dict:

>>> dct = {}
>>> for i in xrange(0,len(lst)): dct[i] = lst[i]

Обратное:

lst = [dct[i] for i in sorted(dct.keys())] 

В любом случае, я думаю, что лучше начать удаление с более высокого индекса, как вы сказали.

person Andrea Ambu    schedule 30.01.2009
comment
Гарантирует ли Python, что [dct [i] for i in dct] всегда будет использовать возрастающие значения i? Если это так, list (dct.values ​​()), безусловно, лучше. - person ; 31.01.2009
comment
Я не думал об этом. Ты прав. Поскольку я читал [здесь] [1], нет гарантии, что элементы будут отобраны в порядке или, по крайней мере, в ожидаемом порядке. Я редактировал. [1]: docs.python.org/library/stdtypes.html#dict. предметы - person Andrea Ambu; 31.01.2009
comment
Этот ответ говорит о словарях в корне неверно. В словаре есть КЛЮЧИ (не ИНДЕКСЫ). Да, пары ключ / значение не зависят друг от друга. Нет, не имеет значения, в каком порядке вы удаляете записи. Преобразование в словарь только для удаления некоторых элементов из списка было бы излишним. - person ToolmakerSteve; 15.12.2013

Чтобы обобщить комментарий от @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]
person Alexander Zhukov    schedule 19.06.2016

Импорт его только по этой причине может быть излишним, но если вы все равно используете pandas, решение простое и понятное:

import pandas as pd
stuff = pd.Series(['a','b','a','c','a','d'])
less_stuff = stuff[stuff != 'a']  # define any condition here
# results ['b','c','d']
person Lorinc Nyitrai    schedule 05.09.2016

some_list.remove(some_list[max(i, j)])

Избегает затрат на сортировку и необходимости явно копировать список.

person Chester    schedule 19.05.2018

Ни один из предложенных до сих пор ответов не выполняет удаление на месте в O (n) по длине списка для произвольного количества индексов для удаления, поэтому вот моя версия:

def multi_delete(the_list, indices):
    assert type(indices) in {set, frozenset}, "indices must be a set or frozenset"
    offset = 0
    for i in range(len(the_list)):
        if i in indices:
            offset += 1
        elif offset:
            the_list[i - offset] = the_list[i]
    if offset:
        del the_list[-offset:]

# Example:
a = [0, 1, 2, 3, 4, 5, 6, 7]
multi_delete(a, {1, 2, 4, 6, 7})
print(a)  # prints [0, 3, 5]
person Pedro Gimeno    schedule 25.10.2019

Вы можете просто использовать np.delete:

list_indices = [0, 2]
original_list = [0, 1, 2, 3]
new_list = np.delete(original_list, list_indices)

Вывод

array([1, 3])

Здесь первый аргумент - это исходный список, второй - индекс или список индексов, которые вы хотите удалить.

Существует третий аргумент, который вы можете использовать в случае наличия ndarrays: ось (0 для строк и 1 для столбцов в случае ndarrays).

person jvel07    schedule 19.11.2020

Как насчет одного из них (я новичок в Python, но они кажутся нормальными):

ocean_basin = ['a', 'Atlantic', 'Pacific', 'Indian', 'a', 'a', 'a']
for i in range(1, (ocean_basin.count('a') + 1)):
    ocean_basin.remove('a')
print(ocean_basin)

['Атлантический', 'Тихоокеанский', 'Индийский']

ob = ['a', 'b', 4, 5,'Atlantic', 'Pacific', 'Indian', 'a', 'a', 4, 'a']
remove = ('a', 'b', 4, 5)
ob = [i for i in ob if i not in (remove)]
print(ob)

['Атлантический', 'Тихоокеанский', 'Индийский']

person user12001090    schedule 30.08.2019

Я собрал все это вместе в list_diff функцию, которая просто принимает два списка в качестве входных данных и возвращает их разницу, сохраняя при этом исходный порядок первого списка.

def list_diff(list_a, list_b, verbose=False):

    # returns a difference of list_a and list_b,
    # preserving the original order, unlike set-based solutions

    # get indices of elements to be excluded from list_a
    excl_ind = [i for i, x in enumerate(list_a) if x in list_b]
    if verbose:
        print(excl_ind)

    # filter out the excluded indices, producing a new list 
    new_list = [i for i in list_a if list_a.index(i) not in excl_ind]
    if verbose:
        print(new_list)

    return(new_list)

Пример использования:

my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'woof']
# index = [0, 3, 6]

# define excluded names list
excl_names_list = ['woof', 'c']

list_diff(my_list, excl_names_list)
>> ['a', 'b', 'd', 'e', 'f']
person mirekphd    schedule 27.12.2019

Вы также можете использовать remove.

delete_from_somelist = []
for i in [int(0), int(2)]:
     delete_from_somelist.append(somelist[i])
for j in delete_from_somelist:
     newlist = somelist.remove(j)
person Jiwon Kim    schedule 15.11.2019