根据来自另一个列表的真/假过滤列表中的元素

问题描述

在vanilla Python 3 中是否有一种惯用的方法屏蔽数组的元素?例如:

a = [True,False,True,False]
b = [2,3,5,7]
b[a]

我希望 b[a] 会返回 [2,5],但出现错误

类型错误:列表索引必须是整数或切片,而不是列表

在 R 中,这按我的预期工作(使用 c() 而不是 [] 来创建列表)。我知道 NumPy 有 MaskedArray 可以做到这一点,我正在寻找一种在普通 Python 中做到这一点的惯用方法。当然,我可以使用循环并遍历掩码列表和元素列表,但我希望有一种更有效的方法来使用更高级别的抽象来掩码元素。

解决方法

您可以使用itertools.compress

>>> from itertools import compress
>>> a = [True,False,True,False]
>>> b = [2,3,5,7]


>>> list(compress(b,a))
[2,5]

请参阅"itertools.compress()" document了解更多详情

,

我认为没有很多方法可以做到这一点,您可以使用 zip

print([y for x,y in zip(a,b) if x])

输出:

[2,5]

您也可以为此创建一个带有 class__getitem__

class index:
    def __init__(self,seq):
        self.seq = seq
    def __getitem__(self,boolseq):
        return [x for x,y in zip(boolseq,self.seq) if y]
print(index(a)[b])

输出:

[2,5]
,

你可以使用列表理解:

[b[i] for i in range(len(a)) if a[i]]

[b[i] for i,mask in enumerate(a) if maks]

在这两种情况下,通过迭代每个元素并仅在掩码为 true 时才插入它来创建列表。

,

你可以使用一个 pandas.Series ,它允许像 dataframe 一样,用一个布尔数组过滤数据

from pandas import Series

a = [True,False]
b = [2,7]

res = Series(b)[a].tolist()

print(res)  # [2,5]
,

在众多选项中,您可以:

1.使用迭代工具 compress

from itertools import compress
a = [True,7]

result_itertools = list(compress(b,a))
print(result_itertools)

2.使用 Filter Function

result_filter = list(filter(lambda x: x[0],zip(a,b)))
for item in result_filter:
    print(item[1])
# 2
# 5

3.使用 List Comprehension

result_comprehension = [value for bool_,value in zip(a,b) if bool_]
print(result_comprehension)
# [2,5]

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...