In einer vorgegebenen Liste und eine Bitmaske, wie kehre ich die Werte an den Indizes, die wahr sind?
Frage
Ich beginne mit der folgenden Liste s
und bitmask 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
Wie kann ich eine Funktion apply_bitmask(s, b)
schreiben, so dass es wieder
['baa', 'have', 'you', 'any']
Lösung
Python 3.1 itertools.compress (oder Python 2.7 ist , wenn Sie noch nicht aktualisiert haben) macht genau das (die Liste Verstehen ist eine echte enge Sekunde):
import itertools
filtered = itertools.compress(s, b)
Beachten Sie, dass dies erzeugt einen Iterator, keine Liste. Spart Speicher, aber wenn Sie zu wiederholen brauchen sie mehrmals oder Verwendung Indizes, können Sie immer list(itertools.compress(s, b))
verwenden. Noch kürzer ist.
Andere Tipps
[ item for item, flag in zip( s, b ) if flag == 1 ]
Sie können mit Listenkomprehensionen :
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.
Dies geschieht zunächst die ursprünglichen zwei Listen und Reißverschluss sie zusammen, so dass Sie eine (temporäre! - das noch in der Liste comp) erhalten Liste von Paaren von Wörtern und ihre Masken - so etwas wie [('baa',1), ('baa',0),...]
. Dann werden nur die Wörter, die eine Maske von 1 (if mask == 1
) haben an den newList
hinzugefügt.
Ein anderes nimmt auf Liste Verständnis, ohne Reißverschluss mit
newList = [item for i, item in enumerate(s) if b[i]]