Mam listę wartości, które muszę filtrować, biorąc pod uwagę wartości na liście wartości logicznych:
list_a = [1, 2, 4, 6]
filter = [True, False, True, False]
Generuję nową listę filtrowaną z następującym wierszem:
filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]
Co skutkuje w:
print filtered_list
[1,4]
Linia działa, ale wygląda (dla mnie) trochę przesadzona i zastanawiałem się, czy istnieje prostszy sposób na osiągnięcie tego samego.
Porady
Podsumowanie dwóch dobrych rad zawartych w poniższych odpowiedziach:
1- Nie nazywaj listy filter
tak jak ja, ponieważ jest to funkcja wbudowana.
2- Nie porównuj rzeczy z True
tymi, które zrobiłem, if filter[idx]==True..
ponieważ jest to niepotrzebne. Wystarczy użyć if filter[idx]
.
if filter[indx] == True
Czy nie używać==
, jeśli chcesz sprawdzić identycznościTrue
, zastosowaniais
. Zresztą w tym przypadku całe porównanie jest bezużyteczne, możesz po prostu użyćif filter[indx]
. Wreszcie: nigdy nie używaj nazwy wbudowanej jako nazwy zmiennej / modułu (mam na myśli nazwęfilter
). Używając czegoś w styluincluded
, żebyif
ładnie się czyta (if included[indx]
).Odpowiedzi:
Szukasz
itertools.compress
:Porównanie czasów (py3.x):
Nie używaj
filter
jako nazwy zmiennej, jest to funkcja wbudowana.źródło
[2, 6]
?list(compress(list_a, [not i for i in fill]))
powinienem wrócić[2, 6]
Tak jak to:
Używanie
zip
jest pythonowym sposobem na iterację wielu sekwencji równolegle, bez konieczności indeksowania. Zakłada się, że obie sekwencje mają tę samą długość (suwak zatrzymuje się po najkrótszym wyczerpaniu). Za pomocąitertools
w tak prostym przypadku to trochę przesada ...Jedną z rzeczy, które robisz w swoim przykładzie, naprawdę powinieneś przestać, jest porównywanie rzeczy z Prawdą, zwykle nie jest to konieczne. Zamiast tego
if filter[idx]==True: ...
możesz po prostu napisaćif filter[idx]: ...
.źródło
Z numpy:
lub zobacz odpowiedź Alexa Szatmary'ego, jeśli list_a może być tablicą numpy, ale nie filtrem
Numpy zwykle daje również duże przyspieszenie
źródło
NumPy
golist
tam, gdzie to możliwe. Ale jeśli i tak musisz użyćlist
, musisz (używającNumPy
rozwiązania) utworzyćnp.array
z obu list, użyć indeksowania boolowskiego i ostatecznie przekonwertować tablicę z powrotem na listę za pomocątolist()
metody. Aby być precyzyjnym, należy uwzględnić te utworzone obiekty w porównaniu czasu. Wtedy używanieitertools.compress
będzie nadal najszybszym rozwiązaniem.Aby to zrobić za pomocą numpy, tj. Jeśli masz tablicę
a
, zamiastlist_a
:źródło
where
.źródło
W Pythonie 3 możesz używać
list_a[filter]
do pobieraniaTrue
wartości. Aby uzyskaćFalse
wartości, użyjlist_a[~filter]
źródło