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


87

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

답변:


115

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

Ahh, enumerate를 사용하라는 유사한 질문을 보았지만 잘못 사용하고 있었던 것 같습니다. 목록을으로 설정 x한 다음 수행 enumerate(x)했지만 4를 열거하는 것이 전부라고 생각합니다. 그게 무슨 일입니까? 도움을 주셔서 감사합니다
Charles Smith

또한 i for i, x목록 이해력에서 할 때 무슨 일이 일어나고 있습니까? i for i예를 들어 또는 유사한 형식 을 보는 데만 익숙 합니다. 기능은 x무엇입니까? 감사합니다
Charles Smith

1
@Amon enumerate은 루프 중에 tuples (ind, value)를 반환합니다. 이제 다음을 사용하여 튜플의 항목을 두 개의 변수에 할당 할 수 있습니다 i, x = (ind, value). 이것이 바로 그 루프에서 일어나는 일입니다.
Ashwini Chaudhary 2014 년

오 지금 무슨 일이 일어나고 있는지 봅니다. 도와 주셔서 감사합니다!
Charles Smith

Python3을 사용하는 모든 사용자의 경우에 itertools.compress솔루션 인을 변경 xrange합니다 range. ( Python 3에서 xrange이름이 변경되었습니다 range.)
MehmedB

64

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

8
이것은 np.where(states)[0]실제로 결과를 사용해야 하는 튜플을 반환합니다
Rufus

17

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)

2

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

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


1

사전 이해 방식 사용,

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}

3
목록 이해력이 아닌 사전 이해력입니다.
Ashwini Chaudhary 2014 년

1

요소 별 곱셈과 집합 사용 :

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


1

다음과 같이하십시오.

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

귀하의 기여에 감사 드리며 StackOverflow에 오신 것을 환영합니다. 그러나 형식을 개선하고 코드에 대한 설명을 추가하려면 편집 도움말 을 참조하십시오 . 감사!
Will
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.