给定一个列表和一个位掩码,如何返回索引为True的值?

10

我从以下列表s和位掩码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

如何编写函数apply_bitmask(s, b),以便它返回

['baa', 'have', 'you', 'any']
4个回答

20

Python 3.1的itertools.compress(如果您尚未升级,则使用Python 2.7's)可以准确实现此功能(列表推导式则是第二选择):

import itertools
filtered = itertools.compress(s, b)

请注意,这会生成一个迭代器,而不是列表。这样可以节省内存,但如果您需要多次迭代它或使用索引,则始终可以使用list(itertools.compress(s, b))。仍然更短。

@Kit:只有在您复制并粘贴文档中给出的示例定义(或立即进行调整,即 result = (i for i, flag in itertools.izip(s, b) if flag) (在Python 3中的zip是Python 2中的izip,它是一个惰性迭代器而不是列表))时才有效。 - user395760

11
[ item for item, flag in zip( s, b ) if flag == 1 ]

8

你可以使用列表推导式

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.

首先将原始的两个列表进行压缩,这样您就可以得到一个临时的列表,其中包含单词和它们的掩码对 - 类似于[('baa',1), ('baa',0),...]。然后只有掩码为1的单词(if mask == 1)才会被添加到newList中。


尽管我会使用 ... if mask,因为他问的是真值,而不是特定的 1 - user395760
没错。我会将它添加到答案中。谢谢delnan。 - Stephen

0

另一种使用列表推导式的方法,不使用zip函数。

newList = [item for i, item in enumerate(s) if b[i]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接