Jak usunąć określony element z tablicy za pomocą języka Python

138

Chcę napisać coś, co usuwa określony element z tablicy. Wiem, że muszę forprzeszukać tablicę w pętli, aby znaleźć element pasujący do zawartości.

Powiedzmy, że mam tablicę e-maili i chcę pozbyć się elementu, który pasuje do jakiegoś ciągu e-mailowego.

Właściwie chciałbym użyć struktury pętli for, ponieważ muszę użyć tego samego indeksu dla innych tablic.

Oto kod, który mam:

for index, item in emails:
    if emails[index] == '[email protected]':
         emails.pop(index)
         otherarray.pop(index)
locoboy
źródło
6
Szukasz list.remove(x)?
Jacob
nie do końca. chciałbym użyć pętli for, aby móc ponownie użyć indeksu
locoboy
4
Nie powinieneś zmieniać listy podczas iteracji po niej.
Jacob
dlaczego nie powinienem tego zrobić? to też nie działa dla mnie.
locoboy

Odpowiedzi:

200

Nie musisz iterować tablicy. Właśnie:

>>> x = ['[email protected]', '[email protected]']
>>> x
['[email protected]', '[email protected]']
>>> x.remove('[email protected]')
>>> x
['[email protected]']

Spowoduje to usunięcie pierwszego wystąpienia, które pasuje do ciągu.

EDYCJA: Po edycji nadal nie musisz jej powtarzać. Po prostu zrób:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]
Bogdana
źródło
1
patrz powyżej, chciałbym użyć pętli for do ponownego użycia tego samego indeksu
locoboy.
Zmodyfikowałem moją odpowiedź. Nadal nie ma potrzeby pętli.
Bogdan
1
Jak po raz pierwszy sprawdzić, czy element istnieje na liście początkowej? Może się zdarzyć, że nie istnieje i nie będziesz musiał go usuwać.
locoboy
17

Używanie filter()i lambdazapewniłby zgrabną i zwięzłą metodę usuwania niechcianych wartości:

newEmails = list(filter(lambda x : x != '[email protected]', emails))

Nie zmienia to e-maili. Tworzy nową listę newEmails zawierającą tylko elementy, dla których funkcja anonimowa zwróciła True.

Ron Kalian
źródło
5

Twoja pętla for nie jest poprawna, jeśli potrzebujesz indeksu w pętli for, użyj:

for index, item in enumerate(emails):
    # whatever (but you can't remove element while iterating)

W twoim przypadku rozwiązanie Bogdana jest w porządku, ale wybór struktury danych nie jest dobry. Konieczność utrzymywania tych dwóch list z danymi z jednej powiązanej z danymi z drugiej w tym samym indeksie jest niewygodna.

Lista krotek (e-mail, inne dane) może być lepsza lub dykt z adresem e-mail jako kluczem.

MatthieuW
źródło
4

Rozsądnym sposobem na zrobienie tego jest użycie zip()i wyrażenie listy / generatora:

filtered = (
    (email, other) 
        for email, other in zip(emails, other_list) 
            if email == '[email protected]')

new_emails, new_other_list = zip(*filtered)

Ponadto, jeśli nie używasz array.array()lub numpy.array(), najprawdopodobniej używasz []lub list(), które dają Ci Listy, a nie Tablice. To nie to samo.

Pillmuncher
źródło
1
Nikt nie jest pewien, jak to jest "rozsądne" w porównaniu z odpowiedzią @ Bogdana, która jest dużo, dużo czystsza.
Jordan Lapp,
Dziękujemy za zwrócenie uwagi, że tablice to nie to samo co listy. Wybrana odpowiedź nie działa w przypadku tablic w wersji 2.7.
EL_DON,
2

Istnieje alternatywne rozwiązanie tego problemu, które dotyczy również zduplikowanych dopasowań.

Rozpoczynamy od 2 list o równej długości: emails, otherarray. Celem jest usunięcie pozycji z obu list dla każdego indeksu, igdzie emails[i] == '[email protected]'.

Można to osiągnąć za pomocą zrozumienia listy, a następnie podzielenia za pomocą zip:

emails = ['[email protected]', '[email protected]', '[email protected]']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= '[email protected]']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['[email protected]', '[email protected]']
print(otherarray)  # ['some', 'details']
jpp
źródło