Gibt es eine einfache Möglichkeit, ein Listenelement nach Wert zu löschen?

942
a = [1, 2, 3, 4]
b = a.index(6)

del a[b]
print(a)

Das Obige zeigt den folgenden Fehler:

Traceback (most recent call last):
  File "D:\zjm_code\a.py", line 6, in <module>
    b = a.index(6)
ValueError: list.index(x): x not in list

Also muss ich das machen:

a = [1, 2, 3, 4]

try:
    b = a.index(6)
    del a[b]
except:
    pass

print(a)

Aber gibt es nicht einen einfacheren Weg, dies zu tun?

zjm1126
quelle
14
Sie berechnen den Index von 6 in Ihrer Liste. Aber 6 ist nicht auf deiner Liste ... also was soll passieren? :)
Johannes Charra
5
Dies hat nichts mit dem Löschen eines Werts in einer Liste zu tun, da Ihr Code die del-Anweisung nicht erreicht. Vielleicht sollten Sie es umbenennen "Wie bekomme ich den Index eines Wertes, der nicht in einer Liste enthalten ist? Offensichtliche Antwort - Sie können nicht.
Dave Kirby
57
@ Dave Nun, nicht wirklich. Er möchte ein Element aus der Liste löschen, unabhängig davon, ob es vorhanden ist oder nicht, um den Index für ein nicht vorhandenes Element nicht abzurufen. Die Frage ist gut gestellt.
ibz
Neben dem Punkt, aber ein nackter exceptist schlechte Praxis . Verwenden Sie except Exceptionauf ein Minimum.
Wjandrea

Antworten:

1564

Verwenden Sie einfach Folgendes, um das erste Vorkommen eines Elements in einer Liste zu entfernen list.remove:

>>> a = ['a', 'b', 'c', 'd']
>>> a.remove('b')
>>> print(a)
['a', 'c', 'd']

Beachten Sie, dass nicht alle Vorkommen Ihres Elements entfernt werden. Verwenden Sie dazu ein Listenverständnis.

>>> a = [10, 20, 30, 40, 20, 30, 40, 20, 70, 20]
>>> a = [x for x in a if x != 20]
>>> print(a)
[10, 30, 40, 30, 40, 70]
Johannes Charra
quelle
144
Schlägt fehl, wenn das Element nicht in der Liste enthalten ist. :)
ibz
21
@ibz Listenverständnis schlägt nicht fehl, auch wenn das Element nicht in der Liste ist, oder?
IsaacS
76
Um zu verdeutlichen, dass jeder überfliegt, "schlägt" es in dem Sinne fehl, dass eine ValueError-Ausnahme ausgelöst wird.
Casey Falk
10
Das Listenverständnis ändert die Listenreferenz. Wenn also irgendwo eine Kopie der Referenz vorhanden ist, folgt das Entfernen nicht.
Sebastien
Was ist die Komplexität von removeist es O (n)?
Rasmi Ranjan Nayak
184

Normalerweise löst Python eine Ausnahme aus, wenn Sie ihm sagen, dass er etwas tun soll, was er nicht kann. Sie müssen also auch Folgendes tun:

if c in a:
    a.remove(c)

oder:

try:
    a.remove(c)
except ValueError:
    pass

Eine Ausnahme ist nicht unbedingt eine schlechte Sache, solange Sie sie erwarten und richtig behandeln.

Dave Webb
quelle
9
Vorbeugung ist besser als Heilung. Wenn Sie zuerst nach außergewöhnlichen Bedingungen suchen können (Beispiel a), sollten Sie dies tun.
Gusdor
82
Während dies in anderen Sprachen zutrifft, ist es in Python "einfacher, um Vergebung als um Erlaubnis zu bitten". docs.python.org/2/glossary.html#term-eafp
Dave Webb
6
@Gusdor: Wenn die Liste von Threads gemeinsam genutzt a.remove(c)wird, kann dies trotz der if c in aPrüfung trotzdem fehlschlagen ( akann nach der c in aPrüfung, aber vor dem a.remove(c)Aufruf in einem anderen Thread geändert werden ). try/exceptoder Schlösser könnten verwendet werden, um die Rennbedingungen zu vermeiden.
JFS
7
@JFSebastian Wenn eine Liste von Threads gemeinsam genutzt wird und Sie keine kritischen Abschnitte anwenden, treten größere Probleme auf.
Gusdor
4
@Gusdor, die Pythonique-Redewendung besteht darin, zu versuchen, ohne zu prüfen, und die Ausnahme abzufangen, wenn sie auftritt. Es ist effizienter (nur eine Suche statt zwei), wenn auch etwas hässlicher
Jeet
80

Du kannst tun

a=[1,2,3,4]
if 6 in a:
    a.remove(6)

aber oben muss 6 in Liste 2 mal gesucht werden, also versuche es außer wäre schneller

try:
    a.remove(6)
except:
    pass
DU
quelle
55

Erwägen:

a = [1,2,2,3,4,5]

Um alle Vorkommen auszuschalten, können Sie die Filterfunktion in Python verwenden. Zum Beispiel würde es so aussehen:

a = list(filter(lambda x: x!= 2, a))

Es würde also alle Elemente von behalten a != 2.

Um nur einen der Gegenstände herauszunehmen, verwenden Sie

a.remove(2)
mathwizurd
quelle
Warum wickelst du dich filter()in einen anderen ein list()? Laut Handbuch wird bereits eine Liste zurückgegeben.
Olaf Dietsche
8
@OlafDietsche In Python 3.x gibt es ein Filterobjekt zurück (in 2.x gibt es eine Liste zurück), daher muss ich "a" in eine Liste umwandeln, damit es eine Funktionalität hat.
Mathwizurd
17

So geht's an Ort und Stelle (ohne Listenverständnis):

def remove_all(seq, value):
    pos = 0
    for item in seq:
        if item != value:
           seq[pos] = item
           pos += 1
    del seq[pos:]
jfs
quelle
Sehr klug - das gefällt mir sehr gut - leider scheint es so ineffizient zu sein wie die beliebteste Antwort. Die Lösung von gil ist für Riesenlisten mit nur wenigen Vorkommen des Werts, den Sie entfernen möchten, tatsächlich viel schneller.
Larold
1
@Larold Der schnellste Weg wäre eine separate Frage. Mein Geld ist im allgemeinen Fall auf Listenverständnis. Diese Lösung sollte wirklich gut funktionieren, wenn der Wert in der Eingabeliste häufig vorkommt und das Listenverständnis nicht verwendet wird. Versuchen Sie Pypy, numpy Daten in Cython. [@ Gill's Antwort ist O(n*n)unnötig (vergleiche 1e6 und 1e12 - du willst letzteres nicht riskieren). while 1: L.remove(value)und Return on ValueErrorfunktioniert möglicherweise gut mit einigen values oder kleinen Listen in CPython.
JFS
13

Wenn Sie wissen, welchen Wert Sie löschen müssen, haben Sie folgende einfache Möglichkeit (so einfach ich mir jedenfalls vorstellen kann):

a = [0, 1, 1, 0, 1, 2, 1, 3, 1, 4]
while a.count(1) > 0:
    a.remove(1)

Du wirst kriegen [0, 0, 2, 3, 4]

Gil
quelle
4
Warum nicht while 1 in a:als Schleifenstruktur verwenden?
TerminalDilettante
12
Hier O(n^2)wäre ein Verständnis O(n).
Mad Physicist
1
Natürlich hat @MadPhysicist recht, und die Version von TerminalDilettante ist viel pythonischer, auch wenn uns die Leistung egal ist. 2013 habe ich gerade angefangen, Python zu lernen, und heutzutage schäme ich mich ziemlich oft für das, was ich damals geschrieben habe.
Gil
11

Eine andere Möglichkeit besteht darin, einen Satz anstelle einer Liste zu verwenden, wenn ein Satz in Ihrer Anwendung anwendbar ist.

IE, wenn Ihre Daten nicht bestellt sind und keine Duplikate haben, dann

my_set=set([3,4,2])
my_set.discard(1)

ist fehlerfrei.

Oft ist eine Liste nur ein praktischer Container für Artikel, die tatsächlich ungeordnet sind. Es werden Fragen gestellt, wie alle Vorkommen eines Elements aus einer Liste entfernt werden können. Wenn Sie überhaupt keine Dupes wollen, ist wieder ein Set praktisch.

my_set.add(3)

ändert my_set nicht von oben.

GreenAsJade
quelle
10

Wie in zahlreichen anderen Antworten angegeben, list.remove()funktioniert dies, aber werfen Sie ein, ValueErrorwenn das Element nicht in der Liste enthalten war. Mit Python 3.4+ gibt es einen interessanten Ansatz, um dies mithilfe des Unterdrückungskontextmanagers zu handhaben :

from contextlib import suppress
with suppress(ValueError):
    a.remove('b')
Felk
quelle
8

Das Suchen eines Werts in einer Liste und das anschließende Löschen dieses Index (falls vorhanden) ist einfacher, indem Sie einfach die Entfernungsmethode der Liste verwenden:

>>> a = [1, 2, 3, 4]
>>> try:
...   a.remove(6)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 3, 4]
>>> try:
...   a.remove(3)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 4]

Wenn Sie dies häufig tun, können Sie es in eine Funktion einschließen:

def remove_if_exists(L, value):
  try:
    L.remove(value)
  except ValueError:
    pass

quelle
8

Dieses Beispiel ist schnell und löscht alle Instanzen eines Werts aus der Liste:

a = [1,2,3,1,2,3,4]
while True:
    try:
        a.remove(3)
    except:
        break
print a
>>> [1, 2, 1, 2, 4]
Chase Adams
quelle
2
Wenn Sie dies tun, sollten Sie wirklich nur breakauf except ValueError.
Anthon
8

In einer Zeile:

a.remove('b') if 'b' in a else None

manchmal ist es nützlich.

Sogar einfacher:

if 'b' in a: a.remove('b')
Andrey Suglobov
quelle
7

Wenn Ihre Elemente unterschiedlich sind, reicht ein einfacher Satzunterschied aus.

c = [1,2,3,4,'x',8,6,7,'x',9,'x']
z = list(set(c) - set(['x']))
print z
[1, 2, 3, 4, 6, 7, 8, 9]
Pagol
quelle
2
Wenn Ihre Elemente unterschiedlich sind und Sie sich nicht um Ordnung kümmern .
Tom Zych
2

Wir können auch .pop verwenden:

>>> lst = [23,34,54,45]
>>> remove_element = 23
>>> if remove_element in lst:
...     lst.pop(lst.index(remove_element))
... 
23
>>> lst
[34, 54, 45]
>>> 
SuperNova
quelle
2

Überschreiben Sie die Liste, indem Sie alles außer den Elementen indizieren, die Sie entfernen möchten

>>> s = [5,4,3,2,1]
>>> s[0:2] + s[3:]
[5, 4, 2, 1]
Kilojoule
quelle
2

Mit einer for-Schleife und einer Bedingung:

def cleaner(seq, value):    
    temp = []                      
    for number in seq:
        if number != value:
            temp.append(number)
    return temp

Und wenn Sie einige, aber nicht alle entfernen möchten:

def cleaner(seq, value, occ):
    temp = []
    for number in seq:
        if number == value and occ:
            occ -= 1
            continue
        else:
            temp.append(number)
    return temp
user7970984
quelle
1
 list1=[1,2,3,3,4,5,6,1,3,4,5]
 n=int(input('enter  number'))
 while n in list1:
    list1.remove(n)
 print(list1)
Ravikiran D.
quelle
Es ist ohne Filterfunktion
Ravikiran D
1

Nehmen wir zum Beispiel an, wir möchten alle Einsen von x entfernen. So würde ich vorgehen:

x = [1, 2, 3, 1, 2, 3]

Dies ist eine praktische Anwendung meiner Methode:

def Function(List, Unwanted):
    [List.remove(Unwanted) for Item in range(List.count(Unwanted))]
    return List
x = Function(x, 1)
print(x)

Und das ist meine Methode in einer einzigen Zeile:

[x.remove(1) for Item in range(x.count(1))]
print(x)

Beide ergeben dies als Ausgabe:

[2, 3, 2, 3, 2, 3]

Hoffe das hilft. PS, bitte beachten Sie, dass dies in Version 3.6.2 geschrieben wurde, so dass Sie es möglicherweise für ältere Versionen anpassen müssen.

Krohnus Melavea
quelle
1

Vielleicht funktionieren Ihre Lösungen mit Ints, aber mit Wörterbüchern funktioniert es bei mir nicht.

In einer Hand hat remove () bei mir nicht funktioniert. Aber vielleicht funktioniert es mit grundlegenden Typen. Ich denke, der folgende Code ist auch die Möglichkeit, Elemente aus der Objektliste zu entfernen.

Andererseits hat 'del' auch nicht richtig funktioniert. In meinem Fall mit Python 3.6: Wenn ich versuche, ein Element aus einer Liste in einem 'for'-Bucle mit dem Befehl' del 'zu löschen, ändert Python den Index im Prozess und der Bucle stoppt vorzeitig vorzeitig. Dies funktioniert nur, wenn Sie Element für Element in umgekehrter Reihenfolge löschen . Auf diese Weise ändern Sie den Array-Index für ausstehende Elemente nicht, wenn Sie ihn durchlaufen

Dann werde ich verwendet:

c = len(list)-1
for element in (reversed(list)):
    if condition(element):
        del list[c]
    c -= 1
print(list)

Dabei ist 'Liste' wie [{'Schlüssel1': Wert1 '}, {' Schlüssel2 ': Wert2}, {' Schlüssel3 ': Wert3}, ...]

Sie können auch mehr Python machen, indem Sie aufzählen:

for i, element in enumerate(reversed(list)):
    if condition(element):
        del list[(i+1)*-1]
print(list)
David Martínez
quelle
0
arr = [1, 1, 3, 4, 5, 2, 4, 3]

# to remove first occurence of that element, suppose 3 in this example
arr.remove(3)

# to remove all occurences of that element, again suppose 3
# use something called list comprehension
new_arr = [element for element in arr if element!=3]

# if you want to delete a position use "pop" function, suppose 
# position 4 
# the pop function also returns a value
removed_element = arr.pop(4)

# u can also use "del" to delete a position
del arr[4]
Brijesh Kushwaha
quelle
0

Dies entfernt alle Instanzen von "-v"aus dem Array sys.argvund beschwert sich nicht, wenn keine Instanzen gefunden wurden:

while "-v" in sys.argv:
    sys.argv.remove('-v')

Sie können den Code in Aktion in einer Datei mit dem Namen sehen speechToText.py:

$ python speechToText.py -v
['speechToText.py']

$ python speechToText.py -x
['speechToText.py', '-x']

$ python speechToText.py -v -v
['speechToText.py']

$ python speechToText.py -v -v -x
['speechToText.py', '-x']
Mike Slinn
quelle
-1

Dies ist meine Antwort, verwenden Sie einfach während und für

def remove_all(data, value):
    i = j = 0
    while j < len(data):
        if data[j] == value:
            j += 1
            continue
        data[i] = data[j]
        i += 1
        j += 1
    for x in range(j - i):
        data.pop()
guoxy2016
quelle