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] == 'something@something.com':
         emails.pop(index)
         otherarray.pop(index)

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 = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']

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]

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 != 'something@something.com', emails))

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


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.


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 == 'something@something.com')

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.


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] == 'something@something.com'.

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

emails = ['abc@def.com', 'something@something.com', 'ghi@jkl.com']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= 'something@something.com']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['abc@def.com', 'ghi@jkl.com']
print(otherarray)  # ['some', 'details']
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.