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

时间:2013-03-18 19:19:32

标签: python map list-comprehension

我有一个值列表:

 a = [1,2,3,4]

相应的布尔人名单:

 b = [True, True, False, True]

我想将b映射到一个这样的值,即我得到所有的值,使得它们在b中的对应值为“True”。所以这个例子的答案是[1,2,4]

我能想到的唯一方法是循环遍历b的元素,获取True的索引,然后在a中检索相应的索引。如下所示:

 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 :(得分:3)

这是一个列表理解,应该做你想要的:

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

另一种方法:

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

答案 1 :(得分:0)

或者这个:

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

答案 2 :(得分:0)

我知道问题是两个列表,并没有提到 numpy 。但是如果您考虑使用它,并且假设a和b是numpy数组,则映射操作变得微不足道:

a[b]

我冒昧地使用1000x元素对建议的选项进行基准测试:

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数组是一个选项,那么它可能是一个可行的解决方案。