So entfernen Sie ein bestimmtes Element mit Python aus einem Array

137

Ich möchte etwas schreiben, das ein bestimmtes Element aus einem Array entfernt. Ich weiß, dass ich fordas Array durchlaufen muss, um das Element zu finden, das dem Inhalt entspricht.

Angenommen, ich habe eine Reihe von E-Mails und möchte das Element entfernen, das mit einer E-Mail-Zeichenfolge übereinstimmt.

Ich möchte eigentlich die for-Schleifenstruktur verwenden, da ich denselben Index auch für andere Arrays verwenden muss.

Hier ist der Code, den ich habe:

for index, item in emails:
    if emails[index] == '[email protected]':
         emails.pop(index)
         otherarray.pop(index)
locoboy
quelle
6
Suchen Sie list.remove(x)?
Jacob
nicht ganz. Ich möchte die for-Schleife verwenden, damit ich den Index
locoboy
4
Sie sollten die Liste nicht ändern, während Sie darüber iterieren.
Jacob
Warum sollte ich das nicht tun? Auch bei mir funktioniert es nicht.
Locoboy
5
Haben Sie sich das angesehen: Du sollst eine Liste während der Iteration nicht
Jacob

Antworten:

199

Sie müssen das Array nicht iterieren. Gerade:

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

Dadurch wird das erste Vorkommen entfernt, das mit der Zeichenfolge übereinstimmt.

BEARBEITEN: Nach Ihrer Bearbeitung müssen Sie immer noch nicht wiederholen. Mach einfach:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]
Bogdan
quelle
1
siehe oben Ich möchte die for-Schleife verwenden, um denselben Index wiederzuverwenden
locoboy
Ich habe meine Antwort bearbeitet. Immer noch keine Schleife nötig.
Bogdan
1
Wie überprüfen Sie zuerst, ob das Element in der initial_list vorhanden ist? Es könnte einen Fall geben, in dem es nicht existiert und Sie es nicht entfernen müssen.
Locoboy
17

Die Verwendung von filter()und lambdawürde eine saubere und knappe Methode zum Entfernen unerwünschter Werte bieten:

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

E-Mails werden dadurch nicht geändert. Es wird die neue Liste newEmails erstellt, die nur Elemente enthält, für die die anonyme Funktion True zurückgegeben hat.

Ron Kalian
quelle
5

Ihre for-Schleife ist nicht richtig, wenn Sie den Index in der for-Schleife benötigen:

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

In Ihrem Fall ist die Bogdan-Lösung in Ordnung, aber Ihre Datenstrukturauswahl ist nicht so gut. Es ist umständlich, diese beiden Listen mit Daten von einer zu Daten von der anderen im selben Index zu führen.

Eine Liste von Tupple (E-Mail, andere Daten) ist möglicherweise besser oder ein Diktat mit E-Mail als Schlüssel.

MatthieuW
quelle
4

Der vernünftige Weg, dies zu tun, besteht darin, zip()einen Listenverständnis- / Generatorausdruck zu verwenden:

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

new_emails, new_other_list = zip(*filtered)

Wenn Sie array.array()oder nicht verwenden numpy.array(), verwenden Sie höchstwahrscheinlich []oder list(), das Ihnen Listen gibt, keine Arrays. Nicht dasselbe.

Pillmuncher
quelle
1
Ich bin mir nicht sicher, wie "vernünftig" das ist, verglichen mit @ Bogdans Antwort, die viel, viel sauberer ist.
Jordan Lapp
Vielen Dank für den Hinweis, dass Arrays nicht mit Listen identisch sind. Die ausgewählte Antwort funktioniert in 2.7 nicht für Arrays.
EL_DON
2

Es gibt eine alternative Lösung für dieses Problem, die sich auch mit doppelten Übereinstimmungen befasst.

Wir beginnen mit 2 gleich langen Listen: emails, otherarray. Ziel ist es, Elemente aus beiden Listen für jeden Index zu entfernen, iin dem emails[i] == '[email protected]'.

Dies kann erreicht werden, indem ein Listenverständnis verwendet und dann aufgeteilt wird über 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
quelle