Jak usunąć element z listy według indeksu

1503

Jak usunąć element z listy według indeksu w Pythonie?

Znalazłem list.removemetodę, ale powiedz, że chcę usunąć ostatni element, jak to zrobić? Wygląda na to, że domyślne usunięcie powoduje przeszukanie listy, ale nie chcę, aby wyszukiwanie było wykonywane.

Joan Venge
źródło
10
@smci: Lista Pythona jest oparta na tablicy: aby usunąć element na środku, musisz przesunąć wszystkie elementy po prawej stronie, aby usunąć lukę, dlatego działa on O(n)w czasie. deque()zapewnia wydajne operacje na obu końcach, ale nie zapewnia wstawiania / wyszukiwania / usuwania O (1) w środku.
jfs
@JFSebastian: Implementacja cPython, tak, dziękuję za poprawienie mnie. Ściśle mówiąc , specyfikacja języka nie określa, jak zaimplementować listę, alternatywne implementacje mogłyby wybrać listę połączoną.
smci
@smci: żadna praktyczna implementacja Pythona nie używałaby O(n)dostępu do indeksu a[i](z powodu list połączonych). Uwaga: implementacja tablicowa zapewnia O(1)dostęp do indeksu.
jfs
@JFSebastian: oczywiście. Zauważyłem tylko, że specyfikacja języka tego nie definiuje , jest to problem z implementacją. (Zaskoczyło mnie, że tak się nie stało)
smci
@smci, jeśli celujesz w to szeroko, nie jestem pewien, jak możesz cokolwiek zoptymalizować.
Nick T

Odpowiedzi:

1740

Użyj deli określ indeks elementu, który chcesz usunąć:

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

Obsługuje również plastry:

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

Oto sekcja z samouczka.

Neil Chowdhury
źródło
53
Dzięki, jaka jest różnica między popem a del?
Joan Venge
37
del jest przeciążony. Na przykład del a usuwa całą listę
Brian R. Bondy
34
kolejny przykład del a [2: 4], usuwa elementy 2 i 3
Brian R. Bondy
307
Pop () zwraca element, który chcesz usunąć. usuń usuń to.
13
Nie widzę tam dowodu „połączonej listy”. Spójrz na svn.python.org/projects/python/trunk/Objects/listobject.c jak PyList_GetItem()zasadniczo zwraca ((PyListObject *)op) -> ob_item[i];- ith element tablicy.
glglgl
648

Prawdopodobnie chcesz pop:

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

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

Domyślnie popbez żadnych argumentów usuwa ostatni element:

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

# now a is ['a', 'b', 'c']
Jarret Hardie
źródło
105
Nie zapomnij o pop (-1). Tak, jest to ustawienie domyślne, ale wolę, aby nie musiałem pamiętać, który koniec popu domyślnie używa.
S.Lott,
282
Nie zgadzam się. Jeśli znasz etymologię „pop” programisty (jest to operacja, która usuwa i zwraca górę struktury danych stosu), to pop()sama w sobie jest bardzo oczywista, choć pop(-1)potencjalnie myląca właśnie dlatego, że jest redundantna.
coredumperror
a.pop (-1), aby usunąć ostatni?
zx1986
14
@ zx1986 a popw większości języków programowania zwykle usuwa ostatni element, podobnie jak w Pythonie. Więc czy podasz -1 czy nic nie będzie takie samo.
Pascal
30
Nawiasem mówiąc, pop()zwraca każdy usunięty element.
Bob Stein
136

Podobnie jak inni wspomniano pop i del są to skuteczne sposoby, aby usunąć element o danym indeksie. Jednak tylko ze względu na ukończenie (ponieważ to samo można zrobić na wiele sposobów w Pythonie):

Używanie plasterków (nie powoduje to usunięcia elementu z oryginalnej listy):

(Również będzie to najmniej wydajna metoda podczas pracy z listą Python, ale może to być przydatne (ale nie wydajne, powtarzam) podczas pracy z obiektami zdefiniowanymi przez użytkownika, które nie obsługują pop, ale definiują 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]

Uwaga: należy pamiętać, że ta metoda nie modyfikuje listy w miejscu jak popi del. Zamiast tego tworzy dwie kopie list (jedną od początku do indeksu, ale bez niego ( a[:index]), a drugą po indeksie do ostatniego elementu ( a[index+1:])) i tworzy nowy obiekt listy, dodając oba. Jest to następnie przypisywane do zmiennej listy ( a). Stary obiekt listy jest zatem wyrejestrowany, a zatem zbierany w pamięci (pod warunkiem, że do oryginalnego obiektu listy nie odwołuje się żadna zmienna inna niż a).

To sprawia, że ​​ta metoda jest bardzo nieefektywna i może również powodować niepożądane skutki uboczne (szczególnie, gdy inne zmienne wskazują oryginalny obiekt listy, który pozostaje niezmodyfikowany).

Dzięki @MarkDickinson za zwrócenie uwagi na to ...

Ta odpowiedź na przepełnienie stosu wyjaśnia pojęcie krojenia.

Zauważ też, że działa to tylko z dodatnimi indeksami.

Podczas używania z obiektami __getitem__metoda musi zostać zdefiniowana, a co ważniejsze, __add__metoda musi zostać zdefiniowana, aby zwrócić obiekt zawierający elementy z obu argumentów operacji.

Zasadniczo działa to z każdym obiektem, którego definicja klasy przypomina:

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 )

Działa to przy użyciu listdefinicji __getitem__i __add__metod.

Porównanie trzech sposobów pod względem wydajności:

Załóżmy, że wstępnie zdefiniowano następujące elementy:

a = range(10)
index = 3

del object[index]Metoda:

Zdecydowanie najbardziej wydajna metoda. Działa to ze wszystkimi obiektami, które definiują __del__metodę.

Demontaż wygląda następująco:

Kod:

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

Demontaż:

 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 metoda:

Jest mniej wydajny niż metoda del i jest używany, gdy trzeba uzyskać usunięty element.

Kod:

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

Demontaż:

 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

Metoda wycinania i dodawania.

Najmniej wydajny.

Kod:

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

Demontaż:

 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

Uwaga: We wszystkich trzech demontażach zignoruj ​​dwie ostatnie linie, które w zasadzie są return None. Również pierwsze dwa wiersze ładują wartości globalne ai index.

Raghav RV
źródło
4
Twoja metoda krojenia nie usuwa elementu z listy: zamiast tego tworzy nowy obiekt listy zawierający wszystko oprócz i-tej pozycji z oryginalnej listy. Oryginalna lista pozostaje niezmodyfikowana.
Mark Dickinson
@MarkDickinson Edytujesz odpowiedź, aby wyjaśnić to samo ... Daj mi znać, czy teraz wygląda dobrze?
Raghav RV
6
Być może odpowiedź nie była całkowicie na temat, ale metoda indeksowania jest przydatna, jeśli chcesz pominąć element z niezmiennego obiektu, takiego jak krotka. pop () i del () nie będą działać w takim przypadku.
Caleb,
6
@ rvraghav93 spośród wszystkich prezentowanych metod podczas całego postu, a = a[:index] + a[index+1 :]-trick był najbezpieczniejszy, jeśli chodzi o ogromne listy. Wszystkie inne metody zakończyły się impasem. Dziękuję bardzo
user3085931,
3
Rzeczywiście, Mark, jesteś zrzędliwy. Ta odpowiedź była tą, którą wolałem, ponieważ była naprawdę pedagogiczna. Nauczyłem się najwięcej z tej odpowiedzi i podanych szczegółów demontażu oraz wpływu na wydajność. Plus metoda krojenia, tak, stwórz kolejny obiekt, ale teraz jest on określony i czasami tego właśnie potrzebujesz.
Yohan Obadia
52

popjest również przydatny do usuwania i przechowywania elementu z listy. Gdzie delfaktycznie niszczy przedmiot.

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

>>> p = x.pop(1)
>>> p
    2
Boatcoder
źródło
24

Jeśli chcesz usunąć określony element pozycji z listy, np. 2, 3 i 7. nie możesz użyć

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

Ponieważ po usunięciu drugiego elementu trzeci usuwany element faktycznie jest czwartym elementem na oryginalnej liście. Możesz odfiltrować 2, 3 i 7 element na oryginalnej liście i uzyskać nową listę, jak poniżej:

new list = [j for i, j in enumerate(my_list) if i not in [2, 3, 7]]
Xiaojia Zhang
źródło
19

To zależy od tego, co chcesz zrobić.

Jeśli chcesz zwrócić usunięty element, użyj pop():

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

Jeśli jednak chcesz tylko usunąć element, użyj del:

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

Dodatkowo delpozwala na korzystanie z plasterków (np del[2:].).

Neil Chowdhury
źródło
18

Ogólnie używam następującej metody:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]
Mayur Koshti
źródło
15

Jeszcze inny sposób usunięcia elementu (ów) z listy według indeksu.

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]

[x: y] wskazuje elementy od indeksu xdo y-1. Gdy deklarujemy tę część listy jako pustą listę ( []), elementy te są usuwane.

Andreas Chatzivasileiadis
źródło
14

Możesz po prostu wyszukać element, który chcesz usunąć. To jest naprawdę proste. Przykład:

    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)

Wyjście: acde

SollyBunny
źródło
6
Podoba mi się to rozwiązanie, ale oczywiście zakłada, że ​​twoja lista nie ma duplikatów.
tommy.carstensen
11

Użyj następującego kodu, aby usunąć element z listy:

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

output = [2, 3, 4]

Jeśli chcesz usunąć dane elementu indeksu z listy, użyj:

list = [1, 2, 3, 4]
list.remove(list[2])
print(list)
output : [1, 2, 4]
jitsm555
źródło
2
Zawiera zastrzeżenie, że lista nie może zawierać duplikatów.
tommy.carstensen
3
To nie jest usuwanie według indeksu, ale usuwanie przez dopasowanie wartości. To może być cenna informacja dla niektórych osób odwiedzających tutaj, ale w ogóle nie próbuje odpowiedzieć na pytanie PO.
Anthon
8

Jak wspomniano wcześniej, najlepszą praktyką jest del (); lub pop (), jeśli chcesz znać wartość.

Alternatywnym rozwiązaniem jest układanie w stos tylko tych elementów, które chcesz:

    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: hmm ... nie będzie działać na ujemne wartości indeksu, zastanowi się i zaktualizuje

Przypuszczam

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

załatałoby to ... ale nagle ten pomysł wydaje się bardzo kruchy. Ciekawy eksperyment myślowy. Wydaje się, że powinien istnieć „właściwy” sposób na wykonanie tego za pomocą funkcji append () / list.

zastanawianie się

litepresence
źródło
1
Która wersja Pythona ma funkcję del()? Dla tej funkcji podajesz listę jako pierwszy argument tej funkcji, a następnie indeks, czy najpierw indeks, a potem listę? Czy zwraca argument listy bez elementu, czy usuwa na miejscu? Wiem o delinstrukcji, ale nie o funkcji o tej samej nazwie.
Anthon
8

Nie brzmi to tak, jakbyś pracował z listą listów, więc powiem krótko. Chcesz użyć pop, ponieważ usunie to elementy, a nie elementy, które są listami, powinieneś do tego użyć del. Aby wywołać ostatni element w pythonie, jest to „-1”

>>> test = ['item1', 'item2']
>>> test.pop(-1)
'item2'
>>> test
['item1']
Mo Ali
źródło
1
pop()i deloba usuwają element z podanego indeksu, niezależnie od tego, czy ten element sam jest listą, czy nie. a = [1, [2, 3], 4]; del a[1]; b = [1, [2, 3], 4]; b.pop(1); assert a == b
Anthon
8

l - lista wartości; musimy usunąć indeksy z listy 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]
Jo Ja
źródło
nie działa, odpowiedź brzmi <map at 0x7f4d54109a58>. a l to zakres (0,20)
Hitesh
7

Użyj funkcji „del” :

del listName[-N]

Na przykład, jeśli chcesz usunąć ostatnie 3 elementy, kod powinien wyglądać następująco:

del listName[-3:]

Na przykład, jeśli chcesz usunąć ostatnie 8 elementów, kod powinien mieć:

del listName[-8:]
lloydyu24
źródło
2
deljest stwierdzeniem . Gdyby to była funkcja, musiałbyś napisaćdel(listame[-N])
Anthon
7

Zostało już wspomniane, jak usunąć pojedynczy element z listy i jakie zalety mają różne metody. Pamiętaj jednak, że usunięcie wielu elementów może powodować błędy:

>>> 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]

Elementy 3 i 8 (nie 3 i 7) z oryginalnej listy zostały usunięte (ponieważ lista została skrócona podczas pętli), co mogło nie być zamierzone. Jeśli chcesz bezpiecznie usunąć wiele indeksów, powinieneś najpierw usunąć elementy o najwyższym indeksie, np. Tak:

>>> 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
źródło
4

Lub jeśli należy usunąć wiele indeksów:

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

Oczywiście wtedy można również zrobić:

print([v for i,v in enumerate(your_list) if i != unwanted_index])
U10 do przodu
źródło
1
Dlaczego nie posortujesz listy indeksów w odwrotnej kolejności, a następnie usuniesz je jeden po drugim? W ten sposób nie musisz tworzyć nowej listy.
Anthon
3

Możesz użyć del lub pop, aby usunąć element z listy na podstawie indeksu. Pop wydrukuje członka, który usuwa z listy, a lista usunie tego członka bez drukowania.

>>> a=[1,2,3,4,5]
>>> del a[1]
>>> a
[1, 3, 4, 5]
>>> a.pop(1)
 3
>>> a
[1, 4, 5]
>>> 
Aashutosh jha
źródło
3

Można użyć del lub pop, ale wolę del, ponieważ możesz określić indeks i plasterki, dając użytkownikowi większą kontrolę nad danymi.

Na przykład, zaczynając od pokazanej listy, można usunąć ostatni element za pomocą deljako plasterek, a następnie można usunąć ostatni element z wyniku za pomocą pop.

>>> l = [1,2,3,4,5]
>>> del l[-1:]
>>> l
[1, 2, 3, 4]
>>> l.pop(-1)
4
>>> l
[1, 2, 3]
pyman
źródło