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

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

Antworten:


199

Sie müssen das Array nicht iterieren. Gerade:

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

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]

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


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.


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

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.


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

Dies kann erreicht werden, indem ein Listenverständnis verwendet und dann aufgeteilt wird über 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']
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.