0

我有一个值列表:

 a = [1,2,3,4]

以及相应的布尔值列表:

 b = [True, True, False, True]

我想将 b 映射到 a 上,以便我得到 a 中的所有值,使得它们在 b 中的对应值为“真”。所以在这种情况下的答案是 [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

有一个更好的方法吗?

4

3 回答 3

4

这是一个应该做你想做的事情的列表理解:

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

另一种方法:

[x for x, y in zip(a, b) if y]
于 2013-03-18T19:21:15.610 回答
1

我知道这个问题陈述了两个列表,并且没有提到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 数组是一种选择,它可能是一个可行的解决方案。

于 2013-03-18T20:12:01.210 回答
0

或这个:

[a[i] for i in range(len(a)) if b[i]]
于 2013-03-18T19:35:03.183 回答