将布尔数组映射为值数组并返回Python中的True实例

0 投票
3 回答
706 浏览
提问于 2025-04-17 19:33

我有一组数值:

 a = [1,2,3,4]

还有一组对应的布尔值:

 b = [True, True, False, True]

我想把布尔值中的'True'对应到数值上,也就是说,我想得到所有在数值列表中对应布尔值为'True'的数值。所以在这个例子中,结果应该是[1,2,4]

我想到的唯一方法就是遍历布尔值列表,找出值为'True'的索引,然后用这些索引去获取数值列表中对应的数值。大概就是这样:

 def maplist(l1, l2):
     # list1 is a list of Booleans to map onto list2
     l2_true = []
     for el in range(len(l1)):
        if l1[el] == True: 
            l2_true.append(l2[el])
     return l2_true

有没有更好的方法可以做到这一点呢?

3 个回答

0

或者这样:

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

我知道这个问题提到了两个列表,并没有提到 numpy。但是如果你考虑使用它,并且假设 a 和 b 是 numpy 数组,那么映射操作就变得非常简单了:

a[b]

我自作主张对建议的选项进行了基准测试,使用了1000个元素:

import numpy

a = [1,2,3,4] * 1000
b = [True, True, False, True] * 1000

def question_fn():
    l2_true = []
    for el in range(len(a)):
        if b[el] == True:
            l2_true.append(a[el])
    return l2_true

def suggestion_1():
    return [v for i, v in enumerate(a) if b[i]]

def suggestion_2():
    return [x for x,y in zip(a,b) if y]

x = numpy.array(a)
y = numpy.array(b)

def using_numpy():
    return x[y]

python -m timeit -s 'import so' 'so.question_fn()'
1000 loops, best of 3: 453 usec per loop

python -m timeit -s 'import so' 'so.suggestion_1()'
10000 loops, best of 3: 203 usec per loop

python -m timeit -s 'import so' 'so.suggestion_2()'
1000 loops, best of 3: 238 usec per loop

python -m timeit -s 'import so' 'so.using_numpy()'
10000 loops, best of 3: 23 usec per loop

请注意,numpy 的计时并不包括转换为数组的时间,否则它会比其他所有建议的解决方案慢得多。不过,如果从一开始就使用 numpy 数组,那可能是一个可行的解决方案。

4

这里有一个列表推导式,它应该能满足你的需求:

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

还有另一种方法:

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

撰写回答