将布尔数组映射为值数组并返回Python中的True实例
我有一组数值:
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]