Tengo una lista de valores que necesito filtrar dados los valores en una lista de booleanos:
list_a = [1, 2, 4, 6]
filter = [True, False, True, False]
Genero una nueva lista filtrada con la siguiente línea:
filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]
lo que resulta en:
print filtered_list
[1,4]
La línea funciona pero parece (para mí) un poco exagerada y me preguntaba si había una manera más simple de lograr lo mismo.
Consejos
Resumen de dos buenos consejos dados en las respuestas a continuación:
1- No nombre una lista filter
como lo hice porque es una función incorporada.
2- No compares cosas con las True
que hice, if filter[idx]==True..
ya que es innecesario. Solo usar if filter[idx]
es suficiente.
if filter[indx] == True
¿Los que no usan==
si desea comprobar la identidad conTrue
, el usois
. De todos modos, en este caso, toda la comparación es inútil, simplemente podría usarlaif filter[indx]
. Por último: nunca use el nombre de un incorporado como nombre de variable / módulo (me refiero al nombrefilter
). Usando algo comoincluded
, para que seif
lea bien (if included[indx]
).Respuestas:
Estas buscando
itertools.compress
:Comparaciones de tiempos (py3.x):
No lo use
filter
como nombre de variable, es una función incorporada.fuente
[2, 6]
?list(compress(list_a, [not i for i in fill]))
debería regresar[2, 6]
Al igual que:
Usar
zip
es la forma pitónica de iterar sobre múltiples secuencias en paralelo, sin necesidad de indexación. Esto supone que ambas secuencias tienen la misma longitud (zip se detiene después de que se agota el más corto). Utilizandoitertools
para un caso tan simple es un poco exagerado ...Una cosa que haces en tu ejemplo que realmente debes dejar de hacer es comparar las cosas con True, esto generalmente no es necesario. En lugar de
if filter[idx]==True: ...
, simplemente puedes escribirif filter[idx]: ...
.fuente
Con numpy:
o vea la respuesta de Alex Szatmary si list_a puede ser una matriz numpy pero no filtrar
Numpy generalmente también te da un gran impulso de velocidad
fuente
NumPy
sobrelist
donde sea posible. Pero si necesita usar delist
todos modos, tiene (usando laNumPy
solución) crear anp.array
partir de ambas listas, usar indexación booleana y finalmente convertir la matriz a la lista con eltolist()
método. Para ser precisos, debe incluir la creación de esos objetos en la comparación de tiempo. Entonces, usaritertools.compress
seguirá siendo la solución más rápida.Para hacer esto usando numpy, es decir, si tiene una matriz
a
, en lugar delist_a
:fuente
where
.fuente
Con python 3 puede usar
list_a[filter]
para obtenerTrue
valores. Para obtenerFalse
valores uselist_a[~filter]
fuente