Come rimuovere un elemento specifico da un array usando Python


138

Voglio scrivere qualcosa che rimuove un elemento specifico da un array. So che devo forpassare in rassegna l'array per trovare l'elemento che corrisponde al contenuto.

Diciamo che ho una serie di e-mail e voglio liberarmi dell'elemento che corrisponde a una stringa di e-mail.

In realtà mi piacerebbe usare la struttura del ciclo for perché ho bisogno di usare lo stesso indice anche per altri array.

Ecco il codice che ho:

for index, item in emails:
    if emails[index] == 'something@something.com':
         emails.pop(index)
         otherarray.pop(index)

6
Stai cercando list.remove(x)?
Jacob,

non proprio. Vorrei usare il ciclo for in modo da poter riutilizzare l'indice
locoboy il

4
Non è necessario modificare l'elenco durante l'iterazione su di esso.
Jacob,

perché non dovrei farlo? inoltre non funziona per me.
locoboy,

Risposte:


200

Non è necessario iterare l'array. Appena:

>>> x = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']

Ciò rimuoverà la prima occorrenza che corrisponde alla stringa.

EDIT: dopo la modifica, non è ancora necessario ripetere l'iterazione. Basta fare:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]

1
vedi sopra vorrei usare il ciclo for per riutilizzare lo stesso indice
locoboy il

Modificato la mia risposta. Non c'è ancora bisogno di loop.
Bogdan,

1
Come si controlla per prima cosa che l'elemento esiste nella lista_iniziale? Potrebbe esserci un caso in cui non esiste e non dovrai rimuoverlo.
locoboy,

17

L'utilizzo filter()e lambdafornirebbe un metodo pulito e conciso per rimuovere i valori indesiderati:

newEmails = list(filter(lambda x : x != 'something@something.com', emails))

Questo non modifica le email. Crea il nuovo elenco newEmails contenente solo elementi per i quali la funzione anonima ha restituito True.


5

Il tuo ciclo for non è corretto, se hai bisogno dell'indice nel ciclo for usa:

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

Nel tuo caso, la soluzione Bogdan è ok, ma la scelta della struttura dei dati non è così buona. Dover mantenere questi due elenchi con i dati di uno relativo ai dati dell'altro allo stesso indice è goffo.

Un elenco di tupple (e-mail, altri dati) potrebbe essere migliore o un dict con e-mail come chiave.


4

Il modo sano per farlo è usare zip()ed un'espressione di elenco / generatore:

filtered = (
    (email, other) 
        for email, other in zip(emails, other_list) 
            if email == 'something@something.com')

new_emails, new_other_list = zip(*filtered)

Inoltre, se non stai usando array.array()o numpy.array(), molto probabilmente stai usando []o list(), che ti danno Elenchi, non Matrici. Non è la stessa cosa


1
Nessuno è sicuro di come sia "sano" rispetto alla risposta di @ Bogdan, che è molto, molto più pulita.
Jordan Lapp,

Grazie per aver sottolineato che gli array non sono gli stessi degli elenchi. La risposta selezionata non funziona sugli array in 2.7.
EL_DON,

2

Esiste una soluzione alternativa a questo problema che si occupa anche di corrispondenze duplicate.

Iniziamo con 2 elenchi di uguale lunghezza: emails, otherarray. L'obiettivo è rimuovere gli elementi da entrambe le liste per ogni indice in icui emails[i] == 'something@something.com'.

Ciò può essere ottenuto utilizzando una comprensione dell'elenco e quindi suddividendolo tramite 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']
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.