Dies war meine Quelle, mit der ich angefangen habe.
Meine Liste
L = [0, 23, 234, 89, None, 0, 35, 9]
Wenn ich das mache:
L = filter(None, L)
Ich bekomme diese Ergebnisse
[23, 234, 89, 35, 9]
Aber das ist nicht was ich brauche, was ich wirklich brauche ist:
[0, 23, 234, 89, 0, 35, 9]
Weil ich das Perzentil der Daten berechne und die 0 einen großen Unterschied macht.
Wie entferne ich den Wert None aus einer Liste, ohne den Wert 0 zu entfernen?
filter
Version:filter(lambda x: x is not None, L)
- Sie könnten dielambda
Verwendung loswerdenpartial
undoperator.is_not
ich denke, aber es lohnt sich wahrscheinlich nicht, da die Listen-Komposition so viel sauberer ist.is_not
existiert! Ich dachte es wäre nuris_
, ich werde das nur zum Spaß hinzufügenis_not
existiert undnot_in
nicht existiert. Ich denke eigentlich, dassnot_in
dies zu einer magischen Methode werden sollte__not_contains__
... siehe eine Frage, die ich vor einiger Zeit gestellt habe, und einen Kommentar, den ich einem Antwortenden gegeben habe ... und ich habe immer noch nicht das Gefühl, dass sie gelöst ist.filterfalse
oder etwas verwenden, je nach Anwendungsfallx > y
nichtnot x <= y
in Python impliziert, weil Sie alles in__lt__
und tun können__le__
, also warum solltex not in y
implizierennot x in y
(vor allem, weilnot in
es einen eigenen Bytecode hat?)FWIW, Python 3 macht dieses Problem einfach:
In Python 2 würden Sie stattdessen ein Listenverständnis verwenden:
quelle
__ne__
so im Gegensatz zupartial
undne
?operator
Moduls.__ne__
?x != y
ruft intern auf,x.__ne__(y)
wobei das ne für "ungleich" steht. Es handelt sich alsoNone.__ne__
um eine gebundene Methode, die True zurückgibt, wenn sie mit einem anderen Wert als None aufgerufen wird . Zum Beispielbm = None.__ne__
mit genanntenbm(10)
Renditen NotImplemented die als wahre Wert undbm(None)
kehrt Falsch .Für Python 2.7 (siehe Raymond's Antwort, für Python 3-Äquivalent):
Wenn Sie wissen möchten, ob etwas "nicht" ist, ist es in Python (und anderen OO-Sprachen) so häufig, dass ich in meiner Common.py (die ich mit "from Common import *" in jedes Modul importiere) folgende Zeilen einfüge:
Um keine Elemente aus einer Liste zu entfernen, gehen Sie einfach wie folgt vor:
Ich finde das leichter zu lesen als das entsprechende Listenverständnis (das Raymond als seine Python 2-Version zeigt).
quelle
partial(is_not, None)
diese Lösung verwenden. Ich glaube, das wird langsamer (obwohl das nicht zu wichtig ist). Aber mit ein paar Importen von Python-Modulen ist in diesem Fall keine benutzerdefinierte FunktionMit dem Listenverständnis kann dies wie folgt erfolgen:
Der Wert von l ist:
quelle
Die Antwort von @jamylak ist ganz nett. Wenn Sie jedoch nicht ein paar Module importieren möchten, um diese einfache Aufgabe zu erledigen, schreiben Sie Ihre eigenen
lambda
an Ort und Stelle:quelle
[x for x in L if x is not None]
Der andere Code war nur eine Ergänzung, die ich ausdrücklich angegeben habe und die ich nicht empfehlen würdeIteration vs Space , Nutzung könnte ein Problem sein. In verschiedenen Situationen kann die Profilerstellung entweder "schneller" und / oder "weniger speicherintensiv" sein.
Der erste Ansatz (wie auch von @jamylak , @Raymond Hettinger und @Dipto vorgeschlagen ) erstellt eine doppelte Liste im Speicher, was für eine große Liste mit wenigen
None
Einträgen kostspielig sein kann .Der zweite Ansatz geht die Liste einmal und dann jedes Mal erneut durch, bis a
None
erreicht ist. Dies könnte weniger speicherintensiv sein und die Liste wird mit der Zeit kleiner. Die Verringerung der Listengröße könnte sich für vieleNone
Einträge vorne beschleunigen , aber der schlimmste Fall wäre, wenn vieleNone
Einträge hinten wären .Parallelisierung und In-Place-Techniken sind andere Ansätze, aber jeder hat seine eigenen Komplikationen in Python. Wenn Sie die Daten und die Anwendungsfälle zur Laufzeit kennen und das Programm profilieren, können Sie mit intensiven Vorgängen oder großen Datenmengen beginnen.
Die Wahl eines der beiden Ansätze spielt in normalen Situationen wahrscheinlich keine Rolle. Es wird eher eine Präferenz der Notation. In der Tat, unter diesen ungewöhnlichen Umständen
numpy
odercython
möglicherweise lohnende Alternativen, anstatt zu versuchen, Python-Optimierungen zu verwalten.quelle
L.count(None)
und dann.remove(None)
mehrmals anrufen , was dazu führt.O(N^2)
Die Situation, die Sie lösen möchten, sollte nicht auf diese Weise behandelt werden, sondern die Daten sollten neu strukturiert werden in eine Datenbank oder Datei stattdessen, wenn es so speicherintensiv ist.O(n^2)
ist nur, wenn die gesamte Liste istNone
.numpy
wäre in der Lage, diese Art von Operation in einer optimierten Weise zu handhabennumpy
in den letzten Jahren verwendet, aber es ist eine separate Fähigkeit. WennL
esnumpy.array
anstelle von Python instanziiert wirdlist
, istL = L[L != numpy.array(None)]
(stackoverflow.com/a/25255015/3003133) wahrscheinlich besser als beide, aber ich kenne die Implementierungsdetails für die Verarbeitung im Vergleich zum Speicher darunter nicht. Es wird mindestens ein Array von Booleschen Werten mit doppelter Länge für die Maske erstellt. Die Syntax eines Vergleichs innerhalb eines Zugriffsoperators (Indexoperators) auf diese Weise ist für mich neu. Diese Diskussion hat mich auch darauf aufmerksam gemachtdtype=object
.quelle
Wenn alles eine Liste von Listen ist, können Sie die Antwort von sir @ Raymond ändern
L = [ [None], [123], [None], [151] ] no_none_val = list(filter(None.__ne__, [x[0] for x in L] ) )
für Python 2 jedochno_none_val = [x[0] for x in L if x[0] is not None] """ Both returns [123, 151]"""
<< list_indice [0] für Variable in List, wenn Variable nicht None >> ist
quelle
Angenommen, die Liste ist wie folgt
Dies gibt nur die Elemente zurück, deren
bool(item) is True
Dies entspricht
So filtern Sie einfach Keine:
Gleichwertig:
Um alle Elemente zu erhalten, die als falsch ausgewertet werden
quelle