Getting indices of True values in a boolean list

前端 未结 7 1914
不思量自难忘°
不思量自难忘° 2020-12-07 11:52

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 True and

相关标签:
7条回答
  • 2020-12-07 12:02

    You can use filter for it:

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

    The range here enumerates elements of your list and since we want only those where self.states is True, we are applying a filter based on this condition.

    For Python > 3.0:

    list(filter(lambda x: self.states[x], range(len(self.states))))
    
    
    0 讨论(0)
  • 2020-12-07 12:05

    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}

    0 讨论(0)
  • 2020-12-07 12:08

    TL; DR: use np.where as it is the fastest option. Your options are np.where, itertools.compress, and list comprehension.

    See the detailed comparison below, where it can be seen np.where outperforms both itertools.compress and also list comprehension.

    >>> 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
    >>> %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
    >>> %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
    >>> %timeit np.where(t)
    179 µs ± 593 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    
    0 讨论(0)
  • 2020-12-07 12:16

    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}
    
    0 讨论(0)
  • 2020-12-07 12:20

    Use enumerate, list.index returns the index of first match found.

    >>> 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:

    >>> 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
    
    0 讨论(0)
  • 2020-12-07 12:24

    Simply do this:

    def which_index(self):
        return [
            i for i in range(len(self.states))
            if self.states[i] == True
        ]
    
    0 讨论(0)
提交回复
热议问题