Как удалить элемент из списка по индексу

1509

Как удалить элемент из списка по индексу в Python?

Я нашел list.removeметод, но говорю, что хочу удалить последний элемент, как мне это сделать? Похоже, что удаление по умолчанию выполняет поиск в списке, но я не хочу, чтобы какой-либо поиск выполнялся.

Джоан Венге
источник
10
@smci: список Python основан на массивах: чтобы удалить элемент посередине, нужно переместить все элементы справа, чтобы убрать пробел, поэтому он работает O(n)во времени. deque()обеспечивает эффективные операции на обоих концах, но не обеспечивает O (1) вставок / поисков / удалений в середине.
JFS
@JFSebastian: реализация cPython, да, спасибо, что поправили меня. Строго говоря, в спецификации языка не указано, как реализовать список, альтернативные реализации могут использовать связанный список.
smci
@smci: ни одна практическая реализация Python не будет использовать O(n)индексный доступ a[i](из-за связанных списков). Примечание: реализация на основе массива обеспечивает O(1)доступ к индексу.
JFS
@JFSebastian: конечно. Я просто отметил, что спецификация языка не определяет это , это проблема реализации. (Я был удивлен, обнаружив, что это не так.)
smci
@ smci, если вы ориентируетесь на это широко, я не уверен, как вы можете надеяться что-либо оптимизировать.
Ник Т

Ответы:

1742

Используйте delи укажите индекс элемента, который вы хотите удалить:

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del a[-1]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8]

Также поддерживает ломтики:

>>> del a[2:4]
>>> a
[0, 1, 4, 5, 6, 7, 8, 9]

Вот раздел из учебника.

Нил Чоудхури
источник
53
Спасибо, в чем разница между поп и дель?
Джоан Венге
37
Дель перегружен. Например, del a удаляет весь список
Brian R. Bondy,
34
другой пример del a [2: 4], удаляет элементы 2 и 3
Брайан Р. Бонди
307
pop () возвращает элемент, который вы хотите удалить. Дель просто удаляет это.
13
Я не вижу там доказательства "связанного списка". Посмотрите на svn.python.org/projects/python/trunk/Objects/listobject.c, как по PyList_GetItem()существу возвращает ((PyListObject *)op) -> ob_item[i];- ith-й элемент массива.
glglgl
649

Вы, вероятно, хотите pop:

a = ['a', 'b', 'c', 'd']
a.pop(1)

# now a is ['a', 'c', 'd']

По умолчанию popбез каких-либо аргументов удаляется последний элемент:

a = ['a', 'b', 'c', 'd']
a.pop()

# now a is ['a', 'b', 'c']
Джаррет Харди
источник
105
Не забудьте поп (-1). Да, это по умолчанию, но я предпочитаю, чтобы мне не приходилось запоминать, какой конечный поп использует по умолчанию
S.Lott
282
Я не согласен. Если вы знаете этимологию программиста «pop» (это операция, которая удаляет и возвращает вершину структуры данных «стека»), то pop()сама по себе она очень очевидна, хотя pop(-1)потенциально может сбить с толку именно потому, что она избыточна.
coredumperror
a.pop (-1) удалить последний?
zx1986
14
@ zx1986 a popв большинстве языков программирования обычно удаляет последний элемент, как в Python. Так что, указываете ли вы -1 или ничего не одно и то же.
Паскаль
30
Кстати, pop()возвращает любой удаленный элемент.
Боб Стейн
136

Как и другие упомянутых попы и дель являются этими эффективными способами удаления элемента из данного индекса. Тем не менее, просто для завершения (поскольку то же самое можно сделать разными способами в Python):

Использование срезов (это не означает удаление элемента из исходного списка):

(Также это будет наименее эффективный метод при работе со списком Python, но это может быть полезно (но неэффективно, я повторяю) при работе с пользовательскими объектами, которые не поддерживают pop, но все же определяют a __getitem__):

>>> a = [1, 2, 3, 4, 5, 6]
>>> index = 3 # Only positive index

>>> a = a[:index] + a[index+1 :]
# a is now [1, 2, 3, 5, 6]

Примечание: обратите внимание, что этот метод не изменяет список на месте, как popи del. Вместо этого он создает две копии списков (один от начала до индекса, но без него ( a[:index]) и один после индекса до последнего элемента ( a[index+1:])) и создает новый объект списка, добавляя оба. Затем он переназначается на переменную списка ( a). Таким образом, старый объект списка разыменовывается и, следовательно, собирается сборщиком мусора (при условии, что на исходный объект списка не ссылаются никакие переменные, кроме a).

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

Спасибо @MarkDickinson за указание на это ...

Этот ответ переполнения стека объясняет концепцию нарезки.

Также обратите внимание, что это работает только с положительными показателями.

При использовании с объектами __getitem__должен быть определен метод, и, что более важно, __add__должен быть определен метод для возврата объекта, содержащего элементы из обоих операндов.

По сути, это работает с любым объектом, чье определение класса похоже на:

class foo(object):
    def __init__(self, items):
        self.items = items

    def __getitem__(self, index):
        return foo(self.items[index])

    def __add__(self, right):
        return foo( self.items + right.items )

Это работает с listкоторой определяет __getitem__и __add__методы.

Сравнение трех способов с точки зрения эффективности:

Предположим, что предопределено следующее:

a = range(10)
index = 3

del object[index]Метод:

Безусловно, самый эффективный метод. Это будет работать со всеми объектами, которые определяют __del__метод.

Разборка заключается в следующем:

Код:

def del_method():
    global a
    global index
    del a[index]

Разборка:

 10    0 LOAD_GLOBAL     0 (a)
       3 LOAD_GLOBAL     1 (index)
       6 DELETE_SUBSCR   # This is the line that deletes the item
       7 LOAD_CONST      0 (None)
      10 RETURN_VALUE
None

pop метод:

Он менее эффективен, чем метод del, и используется, когда вам нужно получить удаленный элемент.

Код:

def pop_method():
    global a
    global index
    a.pop(index)

Разборка:

 17     0 LOAD_GLOBAL     0 (a)
        3 LOAD_ATTR       1 (pop)
        6 LOAD_GLOBAL     2 (index)
        9 CALL_FUNCTION   1
       12 POP_TOP
       13 LOAD_CONST      0 (None)
       16 RETURN_VALUE

Метод среза и добавления.

Наименее эффективный.

Код:

def slice_method():
    global a
    global index
    a = a[:index] + a[index+1:]

Разборка:

 24     0 LOAD_GLOBAL    0 (a)
        3 LOAD_GLOBAL    1 (index)
        6 SLICE+2
        7 LOAD_GLOBAL    0 (a)
       10 LOAD_GLOBAL    1 (index)
       13 LOAD_CONST     1 (1)
       16 BINARY_ADD
       17 SLICE+1
       18 BINARY_ADD
       19 STORE_GLOBAL   0 (a)
       22 LOAD_CONST     0 (None)
       25 RETURN_VALUE
None

Примечание: во всех трех разборках игнорируйте последние две строки, которые в основном есть return None. Также первые две строки загружают глобальные значения aи index.

Рагхав Р.В.
источник
4
Ваш метод нарезки не удаляет элемент из списка: вместо этого он создает новый объект списка, содержащий все элементы, кроме i-й, из исходного списка. Исходный список остается без изменений.
Марк Дикинсон
@MarkDickinson Отредактировал ответ, чтобы уточнить то же самое ... Пожалуйста, дайте мне знать, если это выглядит хорошо сейчас?
Raghav RV
6
Возможно, ответ был не полностью на тему, но метод индексации полезен, если вам нужно опустить элемент из неизменяемого объекта, такого как кортеж. pop () и del () не будут работать в этом случае.
Калеб
6
@ rvraghav93 из всех представленных методов в течение всего поста, a = a[:index] + a[index+1 :]трюк был самым безопасным, когда дело доходит до огромных списков. Все остальные методы оказались в тупике. Так что большое спасибо
user3085931
3
В самом деле, Марк, ты сварливый. Это тот ответ, который я предпочел, потому что он был действительно педагогическим. Из этого ответа я узнал больше всего, а также предоставленные детали разборки и влияние на производительность. Плюс метод нарезки, да, создайте другой объект, но теперь он указан, и иногда это также то, что вам нужно.
Йохан Обадия
52

popтакже полезно удалить и сохранить элемент из списка. Где на delсамом деле разбивает предмет.

>>> x = [1, 2, 3, 4]

>>> p = x.pop(1)
>>> p
    2
boatcoder
источник
24

Если вы хотите удалить определенный элемент позиции в списке, например, 2-й, 3-й и 7-й. ты не можешь использовать

del my_list[2]
del my_list[3]
del my_list[7]

Поскольку после удаления второго элемента третий удаляемый элемент фактически является четвертым элементом в исходном списке. Вы можете отфильтровать 2-й, 3-й и 7-й элемент в исходном списке и получить новый список, как показано ниже:

new list = [j for i, j in enumerate(my_list) if i not in [2, 3, 7]]
сяоцзя чжан
источник
19

Это зависит от того, что вы хотите сделать.

Если вы хотите вернуть удаленный элемент, используйте pop():

>>> l = [1, 2, 3, 4, 5]
>>> l.pop(2)
3
>>> l
[1, 2, 4, 5]

Однако, если вы просто хотите удалить элемент, используйте del:

>>> l = [1, 2, 3, 4, 5]
>>> del l[2]
>>> l
[1, 2, 4, 5]

Кроме того, delпозволяет использовать ломтики (например del[2:]).

Нил Чоудхури
источник
18

Как правило, я использую следующий метод:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]
Маюр Кошти
источник
15

Еще один способ удалить элемент (ы) из списка по индексу.

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# remove the element at index 3
a[3:4] = []
# a is now [0, 1, 2, 4, 5, 6, 7, 8, 9]

# remove the elements from index 3 to index 6
a[3:7] = []
# a is now [0, 1, 2, 7, 8, 9]

a [x: y] указывает на элементы из индекса xв y-1. Когда мы объявляем эту часть списка как пустой список ( []), эти элементы удаляются.

Андреас Хатзивасилеадис
источник
14

Вы можете просто найти элемент, который вы хотите удалить. Это действительно просто. Пример:

    letters = ["a", "b", "c", "d", "e"]
    letters.remove(letters[1])
    print(*letters) # Used with a * to make it unpack you don't have to (Python 3.x or newer)

Выход: acde

SollyBunny
источник
6
Мне нравится это решение, но, конечно, предполагается, что в вашем списке нет дубликатов.
tommy.carstensen
11

Используйте следующий код для удаления элемента из списка:

list = [1, 2, 3, 4]
list.remove(1)
print(list)

output = [2, 3, 4]

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

list = [1, 2, 3, 4]
list.remove(list[2])
print(list)
output : [1, 2, 4]
jitsm555
источник
2
Поставляется с оговоркой, что ваш список не может содержать дубликаты.
tommy.carstensen
3
Это не удаление по индексу, а удаление по соответствующему значению. Это может быть ценной информацией для некоторых людей, посещающих здесь, но не пытается ответить на вопрос ОП вообще.
Anthon
8

Как упоминалось ранее, наилучшей практикой является del (); или pop (), если вам нужно знать значение.

Альтернативное решение состоит в том, чтобы повторно сложить только те элементы, которые вы хотите:

    a = ['a', 'b', 'c', 'd'] 

    def remove_element(list_,index_):
        clipboard = []
        for i in range(len(list_)):
            if i is not index_:
                clipboard.append(list_[i])
        return clipboard

    print(remove_element(a,2))

    >> ['a', 'b', 'd']

eta: хмм ... не будет работать с отрицательными значениями индекса, будет обдумывать и обновлять

Я предполагаю

if index_<0:index_=len(list_)+index_

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

обдумывание

litepresence
источник
1
Какая версия Python имеет функцию del()? Для этой функции вы предоставляете список в качестве первого аргумента этой функции, а затем индекс или сначала индекс, а затем список? Возвращает ли он аргумент списка без элемента или выполняет удаление на месте. Я знаю об delутверждении, но не о функции с тем же именем.
Anthon
8

Не похоже, что вы работаете со списком списков, поэтому я буду кратким. Вы хотите использовать pop, так как он удалит элементы, а не элементы, которые являются списками, для этого следует использовать del. Для вызова последнего элемента в Python это "-1"

>>> test = ['item1', 'item2']
>>> test.pop(-1)
'item2'
>>> test
['item1']
Мо Али
источник
1
pop()и delоба удаляют элемент по указанному индексу, независимо от того, является ли этот элемент списком или нет. a = [1, [2, 3], 4]; del a[1]; b = [1, [2, 3], 4]; b.pop(1); assert a == b
Энтон
8

l - список значений; мы должны удалить индексы из списка inds2rem .

l = range(20)
inds2rem = [2,5,1,7]
map(lambda x: l.pop(x), sorted(inds2rem, key = lambda x:-x))

>>> l
[0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Джо Джа
источник
не работает, ответ <map at 0x7f4d54109a58>. и l это диапазон (0,20)
Hitesh
7

Используйте функцию "del" :

del listName[-N]

Например, если вы хотите удалить последние 3 элемента, ваш код должен быть:

del listName[-3:]

Например, если вы хотите удалить последние 8 элементов, ваш код должен быть:

del listName[-8:]
lloydyu24
источник
2
delэто утверждение . Если бы это была функция, вы должны были бы написатьdel(listame[-N])
Anthon
7

Уже упоминалось, как удалить один элемент из списка и какие преимущества имеют различные методы. Обратите внимание, что удаление нескольких элементов может привести к ошибкам:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in indices:
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 7, 9]

Элементы 3 и 8 (не 3 и 7) исходного списка были удалены (так как список был сокращен во время цикла), что могло и не быть намерением. Если вы хотите безопасно удалить несколько индексов, вы должны сначала удалить элементы с самым высоким индексом, например, так:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in sorted(indices, reverse=True):
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 8, 9]
Kopfgeldjaeger
источник
4

Или, если несколько индексов должны быть удалены:

print([v for i,v in enumerate(your_list) if i not in list_of_unwanted_indexes])

Конечно, тогда также можно сделать:

print([v for i,v in enumerate(your_list) if i != unwanted_index])
U10-Forward
источник
1
Почему бы вам не отсортировать список индексов в обратном порядке, а затем удалить их один за другим? Таким образом, вам не нужно составлять новый список.
Anthon
3

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

>>> a=[1,2,3,4,5]
>>> del a[1]
>>> a
[1, 3, 4, 5]
>>> a.pop(1)
 3
>>> a
[1, 4, 5]
>>> 
Аашутош Джа
источник
3

Можно использовать либо del, либо pop, но я предпочитаю del, поскольку вы можете указать индекс и срезы, предоставляя пользователю больший контроль над данными.

Например, начиная с показанного списка, можно удалить его последний элемент delкак срез, а затем можно удалить последний элемент из результата, используя pop.

>>> l = [1,2,3,4,5]
>>> del l[-1:]
>>> l
[1, 2, 3, 4]
>>> l.pop(-1)
4
>>> l
[1, 2, 3]
pyman
источник