Frage Entfernen Sie alle Werte innerhalb einer Liste aus einer anderen Liste? [Duplikat]


Diese Frage hat hier bereits eine Antwort:

Ich suche nach einer Möglichkeit, alle Werte innerhalb einer Liste aus einer anderen Liste zu entfernen.

Etwas wie das:

a = range(1,10)  
a.remove([2,3,7])  
print a  
a = [1,4,5,6,8,9]  

75
2018-03-25 11:20


Ursprung


Antworten:


>>> a = range(1, 10)
>>> [x for x in a if x not in [2, 3, 7]]
[1, 4, 5, 6, 8, 9]

101
2018-03-25 11:22



Wenn Sie keine wiederholten Werte haben, können Sie die Set-Differenz verwenden.

x = set(range(10))
y = x - set([2, 3, 7])
# y = set([0, 1, 4, 5, 6, 8, 9])

und dann bei Bedarf in die Liste zurück konvertieren.


32
2018-03-29 18:57



Ich suchte nach einem schnellen Weg, um das Thema zu machen, also machte ich einige Experimente mit vorgeschlagenen Wegen. Und ich war überrascht von den Ergebnissen, also möchte ich es mit Ihnen teilen.

Experimente wurden unter Verwendung von Pythonbenchmark Werkzeug und mit

a = range(1,50000) # Source list
b = range(1,15000) # Items to remove

Ergebnisse:

 def comprehension(a, b):
     return [x for x in a if x not in b]

5 Versuche, Durchschnittszeit 12,8 Sek

def filter_function(a, b):
    return filter(lambda x: x not in b, a)

5 Versuche, Durchschnittszeit 12,6 Sek

def modification(a,b):
    for x in b:
        try:
            a.remove(x)
        except ValueError:
            pass
    return a

5 Versuche, Durchschnittszeit 0,27 Sek

def set_approach(a,b):
    return list(set(a)-set(b))

5 Versuche, durchschnittliche Zeit 0,0057 sek

Ich machte auch eine andere Messung mit größeren Eingaben Größe für die letzten zwei Funktionen

a = range(1,500000)
b = range(1,100000)

Und die Ergebnisse:

Zur Modifikation (Methode entfernen) - die durchschnittliche Zeit beträgt 252 Sekunden Für den festgelegten Ansatz - durchschnittliche Zeit ist 0.75 Sekunden

Sie können also sehen, dass dieser Ansatz mit Sets ist bedeutend schneller als andere. Ja, es hält keine ähnlichen Gegenstände, aber wenn Sie es nicht brauchen - es ist für Sie. Und es gibt fast keinen Unterschied zwischen Listenverständnis und Filterfunktion. Die Verwendung von 'Entfernen' ist ~ 50-mal schneller, aber es ändert die Quellliste. Und die beste Wahl ist die Verwendung von Sets - es ist mehr als 1000 Mal schneller als Listenverständnis!


18
2018-05-20 15:16



a = range(1,10)
itemsToRemove = set([2, 3, 7])
b = filter(lambda x: x not in itemsToRemove, a)

oder

b = [x for x in a if x not in itemsToRemove]

Erstellen Sie das Set nicht innerhalb des lambda oder innerhalb des Verständnisses. Wenn Sie dies tun, wird es bei jeder Iteration neu erstellt, wodurch der Punkt der Verwendung eines Satzes überhaupt nicht erreicht wird.


11
2018-03-25 11:26



Andere haben Wege vorgeschlagen, eine neue Liste zu erstellen, nachdem z.B.

newl = [x for x in l if x not in [2,3,7]]

oder

newl = filter(lambda x: x not in [2,3,7], l) 

aber von deiner Frage aus sieht es aus, dass du eine In-Place-Modifikation dafür haben willst, das kannst du tun, das wird auch sein viel viel schneller Wenn die ursprüngliche Liste lang ist und die Elemente weniger entfernt werden sollen

l = range(1,10)
for o in set([2,3,7,11]):
    try:
        l.remove(o)
    except ValueError:
        pass

print l

Ausgabe:     [1, 4, 5, 6, 8, 9]

Ich überprüfe auf ValueError-Ausnahme, so dass es auch funktioniert, wenn Elemente nicht in der ursprünglichen Liste sind.

Auch wenn Sie keine In-Place-Modifikationslösung benötigen S.Mark ist einfacher.


5
2018-03-25 11:38



Der einfachste Weg ist

>>> a = range(1, 10)
>>> for x in [2, 3, 7]:
...  a.remove(x)
... 
>>> a
[1, 4, 5, 6, 8, 9]

Ein mögliches Problem hier ist, dass jedes Mal, wenn Sie remove () aufrufen, alle Elemente in der Liste gemischt werden, um das Loch zu füllen. Also, wenn a wächst sehr groß wird am Ende ziemlich langsam sein.

Auf diese Weise wird eine brandneue Liste erstellt. Der Vorteil ist, dass wir das Mischen des ersten Ansatzes vermeiden

>>> removeset = set([2, 3, 7])
>>> a = [x for x in a if x not in removeset]

Wenn Sie ändern möchten a An Ort und Stelle ist nur eine kleine Änderung erforderlich

>>> removeset = set([2, 3, 7])
>>> a[:] = [x for x in a if x not in removeset]

5
2018-03-25 11:40



>>> a=range(1,10)
>>> for i in [2,3,7]: a.remove(i)
...
>>> a
[1, 4, 5, 6, 8, 9]

>>> a=range(1,10)
>>> b=map(a.remove,[2,3,7])
>>> a
[1, 4, 5, 6, 8, 9]

4
2018-03-25 11:43