小编典典

根据布尔值列表过滤列表

python

我有一个值列表,需要根据给定的布尔值列表中的值进行过滤:

list_a = [1, 2, 4, 6]
filter = [True, False, True, False]

我使用以下行生成一个新的过滤列表:

filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]

结果是:

print filtered_list
[1,4]

这条线工作正常,但是(对我而言)看起来有点过大了,我想知道是否有更简单的方法来实现这一目标。


忠告

以下答案提供了两个好的建议:

1-不要filter像我一样命名列表,因为它是内置函数。

2-不要比较True像我做的事情,if filter[idx]==True..因为这是不必要的。只需使用if filter[idx]就足够了。


阅读 223

收藏
2020-12-20

共1个答案

小编典典

您正在寻找itertools.compress

>>> from itertools import compress
>>> list_a = [1, 2, 4, 6]
>>> fil = [True, False, True, False]
>>> list(compress(list_a, fil))
[1, 4]

时序比较(py3.x):

>>> list_a = [1, 2, 4, 6]
>>> fil = [True, False, True, False]
>>> %timeit list(compress(list_a, fil))
100000 loops, best of 3: 2.58 us per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v]  #winner
100000 loops, best of 3: 1.98 us per loop

>>> list_a = [1, 2, 4, 6]*100
>>> fil = [True, False, True, False]*100
>>> %timeit list(compress(list_a, fil))              #winner
10000 loops, best of 3: 24.3 us per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v]
10000 loops, best of 3: 82 us per loop

>>> list_a = [1, 2, 4, 6]*10000
>>> fil = [True, False, True, False]*10000
>>> %timeit list(compress(list_a, fil))              #winner
1000 loops, best of 3: 1.66 ms per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v] 
100 loops, best of 3: 7.65 ms per loop

不要filter用作变量名,它是一个内置函数。

2020-12-20