在布尔列表中获取True值的索引

时间:2014-01-30 05:04:45

标签: python list

我有一段代码,我应该创建一个交换机。我想返回所有开关的列表。这里“on”将等于True和“off”等于False。所以现在我只想返回所有True值及其位置的列表。这就是我所拥有的,但它只返回第一次出现True的位置(这只是我代码的一部分):

self.states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]

def which_switch(self):
    x = [self.states.index(i) for i in self.states if i == True]

这只返回“4”

7 个答案:

答案 0 :(得分:73)

使用enumeratelist.index返回找到的第一个匹配项的索引。

>>> t = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
>>> [i for i, x in enumerate(t) if x]
[4, 5, 7]

对于大型列表,最好使用itertools.compress

>>> from itertools import compress
>>> list(compress(xrange(len(t)), t))
[4, 5, 7]
>>> t = t*1000
>>> %timeit [i for i, x in enumerate(t) if x]
100 loops, best of 3: 2.55 ms per loop
>>> %timeit list(compress(xrange(len(t)), t))
1000 loops, best of 3: 696 µs per loop

答案 1 :(得分:44)

如果你有可用的numpy:

>>> import numpy as np
>>> states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
>>> np.where(states)[0]
array([4, 5, 7])

答案 2 :(得分:2)

您可以使用过滤器:

filter(lambda x: self.states[x], range(len(self.states)))

range此处列举了您的列表中的元素,因为我们只想要self.statesTrue的内容,我们会根据此条件应用过滤器。

对于Python> 3.0:

list(filter(lambda x: self.states[x], range(len(self.states))))

答案 3 :(得分:1)

只需执行以下操作:

def which_index(self):
    return [
        i for i in range(len(self.states))
        if self.states[i] == True
    ]

答案 4 :(得分:1)

一种更有效的方法是使用 np.where 。请参见下面的详细比较,可以看出 np.where胜过itertools.compress和列表理解力

下面,我将接受的答案(@Ashwini Chaudhary)提出的解决方案与使用numpy.where进行了比较。另请注意,在Python 3中,不推荐使用xrange(),即从python 3.x中删除了xrange()。

>>> from itertools import compress
>>> import numpy as np
>>> t = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]`
>>> t = 1000*t
  • 方法1:使用列表理解
>>> %timeit [i for i, x in enumerate(t) if x]
457 µs ± 1.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
  • 方法2:使用itertools.compress
>>> %timeit list(compress(range(len(t)), t))
210 µs ± 704 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
  • 方法3(最快的方法):使用numpy.where
>>> %timeit np.where(t)
179 µs ± 593 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

答案 5 :(得分:0)

使用字典理解方式,

x = {k:v for k,v in enumerate(states) if v == True}

输入:

states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]

输出:

{4: True, 5: True, 7: True}

答案 6 :(得分:0)

使用逐元素乘法和一组:

>>> states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
>>> set(multiply(states,range(1,len(states)+1))-1).difference({-1})

输出: {4, 5, 7}