Eu tenho o seguinte código:
new_index = index + offset
if new_index < 0:
new_index = 0
if new_index >= len(mylist):
new_index = len(mylist) - 1
return mylist[new_index]
Basicamente, calculo um novo índice e o uso para encontrar algum elemento de uma lista. Para ter certeza de que o índice está dentro dos limites da lista, precisei escrever essas 2 if
instruções espalhadas em 4 linhas. Isso é bastante prolixo, um pouco feio ... Atrevo-me a dizer, é bastante antipitônico .
Existe alguma outra solução mais simples e compacta? (e mais pítônico )
Sim, eu sei que posso usar if else
em uma linha, mas não é legível:
new_index = 0 if new_index < 0 else len(mylist) - 1 if new_index >= len(mylist) else new_index
Eu também sei que posso acorrentar max()
e ficar min()
junto. É mais compacto, mas acho meio obscuro, mais difícil de achar bugs se eu digitar errado. Em outras palavras, não acho muito simples.
new_index = max(0, min(new_index, len(mylist)-1))
clamp = lambda value, minv, maxv: max(min(value, maxv), minv)
Usando a API de arma.sourceforge.net/docs.html#clampRespostas:
Isso é muito claro, na verdade. Muitas pessoas aprendem rapidamente. Você pode usar um comentário para ajudá-los.
fonte
def clamp(n, smallest, largest): return max(smallest, min(n, largest))
helperFunctions.py
? Um módulo separado? E se isso ficar cheio de várias "funções auxiliares" para coisas completamente diferentes?utils.py
por exemplo:
fonte
sorted()
embutido. Muito compacto, mas um pouco obscuro. Enfim, é sempre bom ver outras soluções criativas!min(max())
construção. Muito ligeiramente mais rápido no caso em que o número está na faixa e nenhuma troca é necessária.muitas respostas interessantes aqui, quase iguais, exceto ... qual é mais rápida?
paxdiablo tem !, use o python puro e velho. A versão entorpecida é, talvez não surpreendentemente, a mais lenta de todas. Provavelmente porque está procurando por arrays, onde as outras versões apenas ordenam seus argumentos.
fonte
mm_clip
epy_clip
será igualmente rápido se você usar compilador JIT, como PyPy. Exceto que o primeiro é mais legível e a legibilidade é mais importante na filosofia do Python do que um ligeiro ganho de desempenho na maioria das vezes.Veja numpy.clip :
fonte
clip
éa
, uma “matriz contendo elementos para recortar”. Então você teria que escrevernumpy.clip([index], …
, nãonumpy.clip(index, …
.Encadear
max()
emin()
unir é o idioma normal que já vi. Se você achar difícil de ler, escreva uma função auxiliar para encapsular a operação:fonte
O que aconteceu com minha amada linguagem Python legível? :-)
Sério, basta torná-lo uma função:
em seguida, basta chamá-lo com algo como:
Ou uma solução mais simples e flexível, onde você mesmo faz o cálculo:
Se você quiser, pode até mesmo fazer do min / max uma lista para que pareça mais "matematicamente puro":
fonte
min
emax
são muito mais claros do que um monte de condicionais. (Não sei para queadd
serve - basta dizerclamp(val + 7, 0, 42)
.)Este parece mais pitônico para mim:
Alguns testes:
fonte
Se o seu código parecer muito pesado, uma função pode ajudar:
fonte
Evite escrever funções para tarefas tão pequenas, a menos que você as aplique com frequência, pois isso irá bagunçar seu código.
para valores individuais:
para listas de valores:
fonte