[python] 부울 목록에서 True 값 인덱스 가져 오기

배전반을 만들어야하는 코드가 있습니다. 켜져있는 모든 스위치 목록을 반환하고 싶습니다. 여기서 “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”만 반환됩니다.



답변

를 사용 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]

거대한 목록의 경우 다음을 사용하는 것이 좋습니다 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


답변

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])


답변

TL; DR : np.where가장 빠른 옵션이므로 사용 하십시오. 옵션은 np.where, itertools.compresslist comprehension입니다.

그것을 볼 수 있습니다 아래의 자세한 비교, 참조 np.where성능이 뛰어을 모두 itertools.compress도와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
  • 방법 1 : 사용 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)
  • 방법 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)


답변

필터를 사용할 수 있습니다.

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

range여기에 목록의 요소를 열거하고 우리가 어디에 만 원하기 때문에 self.states한다 True, 우리는이 조건에 따라 필터를 적용됩니다.

Python> 3.0의 경우 :

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


답변

사전 이해 방식 사용,

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}


답변

요소 별 곱셈과 집합 사용 :

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


답변

다음과 같이하십시오.

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