Eu tenho um trecho do meu código onde devo criar um painel de controle. Quero retornar uma lista de todos os interruptores que estão ativados. Aqui, "on" será igual True
e "off" será igual False
. Agora, quero apenas retornar uma lista de todos os True
valores e suas posições. Isso é tudo que tenho, mas ele apenas retorna a posição da primeira ocorrência de True
(esta é apenas uma parte do meu código):
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]
Isso retorna apenas "4"
x
, então fazendo,enumerate(x)
mas acho que tudo que eu estava fazendo era enumerar 4? É isso que estava acontecendo? Obrigado pela ajudai for i, x
a compreensão da lista? Só estou acostumado a veri for i
por exemplo, ou um formato semelhante, qual é a função dex
? Obrigadoenumerate
retorna um tuplas (ind, valor) durante o loop, agora podemos atribuir os itens da tupla a duas variáveis usando:i, x = (ind, value)
. Isso é exatamente o que está acontecendo nesse loop.itertools.compress
solução, altere oxrange
pararange
. (xrange
foi renomeado pararange
em Python 3.)Se você tiver numpy disponível:
>>> 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])
fonte
np.where(states)[0]
o uso real dos resultadosTL; DR : use
np.where
, pois é a opção mais rápida. Suas opções sãonp.where
,itertools.compress
elist comprehension
.Veja a comparação detalhada abaixo, onde pode ser visto que
np.where
supera ambositertools.compress
e tambémlist 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
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)
itertools.compress
>>> %timeit list(compress(range(len(t)), t)) 210 µs ± 704 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
numpy.where
>>> %timeit np.where(t) 179 µs ± 593 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
fonte
Você pode usar o filtro para isso:
filter(lambda x: self.states[x], range(len(self.states)))
O
range
here enumera os elementos da sua lista e como queremos apenas aqueles ondeself.states
estáTrue
, estamos aplicando um filtro com base nesta condição.Para Python> 3.0:
list(filter(lambda x: self.states[x], range(len(self.states))))
fonte
Use a forma de compreensão do dicionário,
x = {k:v for k,v in enumerate(states) if v == True}
Entrada:
states = [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
Resultado:
{4: True, 5: True, 7: True}
fonte
Usando a multiplicação por elemento e um conjunto:
>>> 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})
Resultado:
{4, 5, 7}
fonte
Basta fazer isso:
def which_index(self): return [ i for i in range(len(self.states)) if self.states[i] == True ]
fonte