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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 22:52:47  来源:igfitidea点击:

Getting indices of True values in a boolean list

pythonlist

提问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.statesTrue,我们将基于这个条件的过滤器。

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.compresslist 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)