5

のようなブールリストが与えられた場合、元のリストのTruthy要素のインデックス(ゼロインデックスではなく1から始まる)を含むリスト/タプルを取得する最も簡単[True, False, False, True, False, True]な方法は何ですか?したがって、上記のリストの場合は、またはを返す必要があります。[1, 4, 6](1, 4, 6)

私は次のようなジェネレーターを使用していました:

def get_truthy_ones(self, bool_list):
    return (idx + 1 for idx, value in enumerate(bool_list) if value)

ただし、ジェネレータをエンコードしないため、結果をJSONオブジェクトにエンコードする場合は問題が発生します。JSON

4

4 に答える 4

12
[i for i, elem in enumerate(bool_list, 1) if elem]
于 2012-10-25T20:17:44.553 に答える
3

かっこを角かっこに切り替えて、ジェネレータの代わりにリストを返します。

def get_truthy_ones(self, bool_list):
    return [idx for idx, value in enumerate(bool_list, 1) if value]

または、元の関数を使用して、ジェネレーターからリストを作成します。

list(get_truthy_ones(self, bool_list))
于 2012-10-25T20:18:34.860 に答える
2

それができるという理由だけで、。を使用した代替バージョンitertools.compress()。これは他の例よりも読みにくいと思うので、お勧めしません。

>>> list(itertools.compress(*zip(*enumerate([True, False, False, True, False, True], 1))))
[1, 4, 6]

編集:

python -m timeit -s "import itertools" -s "values = [True, False]*10000" "list(itertools.compress(*zip(*enumerate(values, 1))))"
100 loops, best of 3: 2.88 msec per loop

python -m timeit -s "import itertools" -s "values = [True, False]*10000" "[index for index, value in enumerate(values, 1) if value]"
1000 loops, best of 3: 1.11 msec per loop

実際、かなり遅いので、絶対に使用しないでください。

于 2012-10-25T20:24:09.833 に答える
1

リストをnumpy配列に変換する方法がある場合は、numpy.where()を使用する方が高速です。

> python -m timeit -s "import numpy" -s "values = numpy.array([True, False]*10000)" "numpy.where(values)"
1000 loops, best of 3: 392 usec per loop

> python -m timeit -s "import itertools" -s "values = [True, False]*10000" "[index for index, value in enumerate(values, 1) if value]"
100 loops, best of 3: 2.1 msec per loop

しかし、私はセットアップで変換を行うことによってここで不正行為をしている可能性があります。

于 2012-10-25T20:52:11.697 に答える