Python 在布尔列表中获取 True 值的索引
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21448225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting indices of True values in a boolean list
提问by Charles Smith
I have a piece of my code where I'm supposed to create a switchboard. I want to return a list of all the switches that are on. Here "on" will equal Trueand "off" equal False. So now I just want to return a list of all the Truevalues and their position. This is all I have but it only return the position of the first occurrence of True(this is just a portion of my code):
我有一段代码,我应该在其中创建一个总机。我想返回所有打开的开关的列表。这里的“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]
This only returns "4"
这只返回“4”
采纳答案by Ashwini Chaudhary
Use enumerate, list.indexreturns the index of first match found.
使用enumerate,list.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]
For huge lists, it'd be better to use itertools.compress:
对于巨大的列表,最好使用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
回答by sashkello
You can use filter for it:
您可以使用过滤器:
filter(lambda x: self.states[x], range(len(self.states)))
The rangehere enumerates elements of your list and since we want only those where self.statesis True, we are applying a filter based on this condition.
在range这里列举的清单的元素,因为我们只想要那些self.states是True,我们将基于这个条件的过滤器。
For Python > 3.0:
对于 Python > 3.0:
list(filter(lambda x: self.states[x], range(len(self.states))))
回答by Beginner
Use dictionary comprehension way,
使用字典理解方式,
x = {k:v for k,v in enumerate(states) if v == True}
Input:
输入:
states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
Output:
输出:
{4: True, 5: True, 7: True}
回答by jterrace
If you have numpy available:
如果你有 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])
回答by Nate
Using element-wise multiplication and a set:
使用逐元素乘法和一个集合:
>>> 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})
Output:
{4, 5, 7}
输出:
{4, 5, 7}
回答by ArnabJyoti Thakuria
Simply do this:
只需这样做:
def which_index(self):
return [
i for i in range(len(self.states))
if self.states[i] == True
]
回答by Meysam Sadeghi
A much more efficient way is to use np.where. See the detailed comparison below, where it can be seen np.whereoutperforms both itertools.compressand also list comprehension.
更有效的方法是使用np.where. 请参阅下面的详细比较,可以看出它的np.where表现优于itertools.compress和list comprehension。
Below I have compared the solutions proposed by the accepted answer (@Ashwini Chaudhary) with using numpy.where. Also note that in Python 3, xrange() is deprecated, i.e. xrange() is removed from python 3.x.
下面我将接受的答案 (@Ashwini Chaudhary) 提出的解决方案与使用numpy.where. 另请注意,在 Python 3 中,xrange() 已弃用,即 xrange() 从 python 3.x 中删除。
>>> 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
- Method 1: Using
list comprehension
- 方法一:使用
list comprehension
>>> %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)
- Method 2: Using
itertools.compress
- 方法二:使用
itertools.compress
>>> %timeit list(compress(range(len(t)), t))
210 μs ± 704 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
- Method 3 (the fastest method): Using
numpy.where
- 方法 3(最快的方法):使用
numpy.where
>>> %timeit np.where(t)
179 μs ± 593 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

