Dada una lista y una máscara de bits, ¿cómo puedo devolver los valores en los índices que son verdaderas?
Pregunta
Comienzo con la siguiente lista s
y máscara de bits b
:
s = ['baa', 'baa', 'black', 'sheep', 'have', 'you', 'any', 'wool']
b = [1, 0, 0, 0, 1, 1, 1, 0] # or any iterable with boolean values
¿Cómo puedo escribir alguna función apply_bitmask(s, b)
para que vuelva
['baa', 'have', 'you', 'any']
Solución
itertools.compress (o de Python 2.7 si no se ha actualizado todavía) hace exactamente eso (la lista la comprensión es un verdadero cercano segundo lugar):
import itertools
filtered = itertools.compress(s, b)
Tenga en cuenta que esto produce un iterador, no una lista. Ahorra memoria, pero si usted necesita para iterar varias veces o índices de uso, siempre se puede utilizar list(itertools.compress(s, b))
. Aún más corto.
Otros consejos
[ item for item, flag in zip( s, b ) if flag == 1 ]
Se puede usar listas por comprensión :
newList = [word for (word, mask) in zip(s,b) if mask]
# Note: Could also use 'if mask == blah', if mask is not a boolean-compatible type.
Esta primera toma las dos listas originales, y cremalleras juntos, por lo que se obtiene un (temporal - esto es aún dentro de la lista de los!) lista de pares de palabras y sus máscaras - algo así como [('baa',1), ('baa',0),...]
. Entonces sólo las palabras que tienen una máscara de 1 (if mask == 1
) se añaden a la newList
.
Otra toma en la lista por comprensión, sin necesidad de utilizar postal
newList = [item for i, item in enumerate(s) if b[i]]