programing

부울 리스트에서 True 값의 인덱스 가져오기

easyjava 2023. 4. 19. 23:35
반응형

부울 리스트에서 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,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)

요소별 곱셈 및 집합 사용:

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

필터는 다음과 같이 사용할 수 있습니다.

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

사전 이해 방식을 사용합니다.

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}

간단하게 다음 작업을 수행합니다.

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

저는 @meysham 답변과 다른 벤치마크 결과를 얻었습니다.이 검정에서는 압축이 가장 빠른 것 같습니다(피톤 3.7).

from itertools import compress
import numpy as np
t = [True, False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]

%timeit [i for i, x in enumerate(t) if x]
%timeit list(compress(range(len(t)), t))
%timeit list(filter(lambda x: t[x], range(len(t))))
%timeit np.where(t)[0]

# 2.54 µs ± 400 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# 2.67 µs ± 600 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# 6.22 µs ± 624 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# 6.52 µs ± 768 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
t = 1000*t
%timeit [i for i, x in enumerate(t) if x]
%timeit list(compress(range(len(t)), t))
%timeit list(filter(lambda x: t[x], range(len(t))))
%timeit np.where(t)[0]

# 1.68 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# 947 µs ± 105 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# 3.96 ms ± 97 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# 2.14 ms ± 45.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

대괄호가 있는 부울 마스크 배열을 사용하여 필터링할 수 있습니다. 이 속도는np.where

>>> states = [True, False, False, True]
>>> np.arange(len(states))[states]
array([0, 3])
>>> size = 1_000_000
>>> states = np.arange(size) % 2 == 0
>>> states 
array([ True, False,  True, ..., False,  True, False])
>>> true_index = np.arange(size)[states]
>>> len(true_index)
500000
>>> true_index
array([     0,      2,      4, ..., 999994, 999996, 999998])

언급URL : https://stackoverflow.com/questions/21448225/getting-indices-of-true-values-in-a-boolean-list

반응형