Ich habe eine Liste von Werten, die ich filtern muss, wenn die Werte in einer Liste von Booleschen Werten enthalten sind:
list_a = [1, 2, 4, 6]
filter = [True, False, True, False]
Ich erstelle eine neue gefilterte Liste mit der folgenden Zeile:
filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]
was in ... endet:
print filtered_list
[1,4]
Die Linie funktioniert, sieht aber (für mich) etwas übertrieben aus und ich habe mich gefragt, ob es einen einfacheren Weg gibt, dasselbe zu erreichen.
Ratschläge
Zusammenfassung von zwei guten Ratschlägen in den folgenden Antworten:
1- Benennen Sie eine Liste nicht filter
wie ich, da es sich um eine integrierte Funktion handelt.
2- Vergleichen Sie Dinge nicht so, True
wie ich es getan habe, if filter[idx]==True..
da dies unnötig ist. Nur zu benutzen if filter[idx]
ist genug.
if filter[indx] == True
Sie nicht verwenden ,==
wenn Sie für Identität überprüfen möchten mitTrue
, Verwendungis
. Wie auch immer, in diesem Fall ist der gesamte Vergleich nutzlos, Sie könnten ihn einfach verwendenif filter[indx]
. Zuletzt: Verwenden Sie niemals den Namen eines integrierten Systems als Variablen- / Modulnamen (ich beziehe mich auf den Namenfilter
). Mit so etwas wieincluded
, damit dasif
schön liest (if included[indx]
).Antworten:
Sie suchen
itertools.compress
:Zeitvergleiche (py3.x):
Nicht
filter
als Variablenname verwenden, sondern eine integrierte Funktion.quelle
[2, 6]
?list(compress(list_a, [not i for i in fill]))
sollte zurückkehren[2, 6]
Wie so:
Die Verwendung
zip
ist die pythonische Methode, um mehrere Sequenzen parallel zu durchlaufen , ohne dass eine Indizierung erforderlich ist. Dies setzt voraus, dass beide Sequenzen die gleiche Länge haben (Zip stoppt, nachdem die kürzeste abgelaufen ist). Die Verwendungitertools
für einen so einfachen Fall ist ein bisschen übertrieben ...Eine Sache, die Sie in Ihrem Beispiel tun sollten, ist, Dinge mit True zu vergleichen. Dies ist normalerweise nicht erforderlich. Stattdessen
if filter[idx]==True: ...
können Sie einfach schreibenif filter[idx]: ...
.quelle
Mit numpy:
oder sehen Sie sich die Antwort von Alex Szatmary an, wenn list_a ein numpy-Array sein kann, aber kein Filter
Numpy gibt dir normalerweise auch einen großen Geschwindigkeitsschub
quelle
NumPy
über ,list
soweit möglich. Wenn Sie eslist
trotzdem verwenden müssen, müssen Sie (mithilfe derNumPy
Lösung)np.array
aus beiden Listen erstellen , die boolesche Indizierung verwenden und schließlich das Array mit dertolist()
Methode wieder in eine Liste konvertieren . Um genau zu sein, sollten Sie diese Objekterstellung in den Zeitvergleich einbeziehen. Dann ist die Verwendungitertools.compress
immer noch die schnellste Lösung.Verwenden Sie dazu numpy, dh wenn Sie ein Array haben
a
, anstelle vonlist_a
:quelle
where
.quelle
Mit Python 3 können
list_a[filter]
SieTrue
Werte abrufen. UmFalse
Werte zu erhalten , verwenden Sielist_a[~filter]
quelle