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.


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.


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

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.


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

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

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:].).


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]

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.


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


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]

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ę


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

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]

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

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]

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

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

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]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.