如何使用另一个列表中的布尔值屏蔽列表



我有一个这样的列表:

x = [True, False, True, False]

和这样的列表:

y = [a, b, c, d]

我想在y上屏蔽x以获得此输出:

output = [a, c]

我知道如何使用while/for循环来实现这一点,但理想情况下,我正在寻找一个使用列表理解的优雅的一行代码。

您可以使用zip和列表理解,根据x:中相应的真值对y执行过滤操作

x = [True, False, True, False]
y = ["a", "b", "c", "d"]
print([b for a, b in zip(x, y) if a])

输出:

['a', 'c']

itertools.compress也这样做:

>>> from itertools import compress
>>> x = [True, False, True, False]
>>> y = ["a", "b", "c", "d"]
>>> list(compress(y, x))
['a', 'c']

我认为最简单的方法是使用numpy:

import numpy as np
>>> x = [True, False, True, False]
>>> y = ['a', 'b', 'c', 'd']
>>> np.array(y)[x]
array(['a', 'c'], dtype='<U1')

如果没有numpy,你也可以在列表中枚举理解:

>>> [i for idx, i in enumerate(y) if x[idx]]
['a', 'c']

有几种方法可以做到这一点。

最简单的方法是将两个列表压缩在一起,并使用列表理解来保留您想要的项目。

x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
print([item for keep, item in zip(x, y) if keep])

您也可以将y数组转换为numpy数组,并使用x数组来屏蔽numpy数组。

import numpy as np
x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
print(list(np.array(y)[x]))

最后,您可以创建一个空列表,使用x和y数组的索引遍历它们,如果x中的相应元素为True,则可以将y中的元素追加到空列表中。

x = [True, False, True, False]
y = ['a', 'b', 'c', 'd']
temp = []
for index in range(len(y)):
if x[index]:
temp.append(y[index])
print(temp)

如果已经有一些函数为每个元素y返回True/False,请使用filter((,例如:

list(filter(lambda x: x < 'c' , y))

my_iter = iter([True, False, True, False])
list(filter(lambda x: next(my_iter), y))

这很容易解决。考虑正确地写下你的清单:

x = [True, False, True, False]
y = [a, b, c, d]  # assuming that a, b, c and d are some kind of object
output = []
for i, k in enumerate(x):
if k:
output.append(x[i])