0

値のリストがあります:

 a = [1,2,3,4]

対応するブール値のリスト:

 b = [True, True, False, True]

b の対応する値が「True」になるように、a のすべての値を取得するように、b を a にマップしたいと考えています。したがって、この場合の答えは [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

質問には2つのリストが記載されており、 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 に答える