J'ai une liste de valeurs que je dois filtrer étant donné les valeurs dans une liste de booléens:
list_a = [1, 2, 4, 6]
filter = [True, False, True, False]
Je génère une nouvelle liste filtrée avec la ligne suivante:
filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]
ce qui se traduit par:
print filtered_list
[1,4]
La ligne fonctionne mais me semble un peu exagérée et je me demandais s'il y avait un moyen plus simple d'y parvenir.
Des conseils
Résumé de deux bons conseils donnés dans les réponses ci-dessous:
1- Ne nommez pas une liste filter
comme je l'ai fait car c'est une fonction intégrée.
2- Ne comparez pas les choses à ce True
que j'ai fait if filter[idx]==True..
car c'est inutile. Il suffit d'utiliser if filter[idx]
.
if filter[indx] == True
ne pas utiliser==
si vous souhaitez vérifier l'identité avecTrue
, utilisezis
. Quoi qu'il en soit, dans ce cas, toute la comparaison est inutile, vous pouvez simplement utiliserif filter[indx]
. Enfin: n'utilisez jamais le nom d'un élément intégré comme nom de variable / module (je fais référence au nomfilter
). En utilisant quelque chose commeincluded
, pour que leif
lit bien (if included[indx]
).Réponses:
Vous recherchez
itertools.compress
:Comparaisons de temps (py3.x):
Ne pas utiliser
filter
comme nom de variable, c'est une fonction intégrée.la source
[2, 6]
?list(compress(list_a, [not i for i in fill]))
devrait revenir[2, 6]
Ainsi:
L'utilisation
zip
est la manière pythonique d'itérer sur plusieurs séquences en parallèle, sans avoir besoin d'indexation. Cela suppose que les deux séquences ont la même longueur (le zip s'arrête après la fin du plus court). Utiliseritertools
pour un cas aussi simple est un peu exagéré ...Une chose que vous faites dans votre exemple que vous devriez vraiment arrêter de faire est de comparer les choses à True, ce n'est généralement pas nécessaire. Au lieu de
if filter[idx]==True: ...
, vous pouvez simplement écrireif filter[idx]: ...
.la source
Avec numpy:
ou voir la réponse d'Alex Szatmary si list_a peut être un tableau numpy mais pas un filtre
Numpy vous donne généralement une grande augmentation de vitesse
la source
NumPy
pluslist
si possible. Mais si vous devezlist
quand même utiliser , vous devez (en utilisant laNumPy
solution) créer ànp.array
partir des deux listes, utiliser l'indexation booléenne et enfin convertir le tableau en liste avec latolist()
méthode. Pour être précis, vous devez inclure la création de ces objets dans la comparaison temporelle. Ensuite, l'utilisationitertools.compress
sera toujours la solution la plus rapide.Pour ce faire, utilisez numpy, c'est-à-dire si vous avez un tableau
a
, au lieu delist_a
:la source
where
.la source
Avec python 3, vous pouvez utiliser
list_a[filter]
pour obtenir desTrue
valeurs. Pour obtenir desFalse
valeurs, utilisezlist_a[~filter]
la source