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

How to mask a list using boolean values from another list

我有一个这样的列表:

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]  # 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])

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

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

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)