Eu tenho um código parecido com este:
thing_index = thing_list.index(thing)
otherfunction(thing_list, thing_index)
ok isso é simplificado, mas essa é a idéia. Agora thing
pode não estar realmente na lista, caso em que desejo passar -1 como thing_index
. Em outras linguagens, isso é o que você esperaria index()
retornar se não conseguisse encontrar o elemento. Na verdade, ele lança um ValueError
.
Eu poderia fazer isso:
try:
thing_index = thing_list.index(thing)
except ValueError:
thing_index = -1
otherfunction(thing_list, thing_index)
Mas isso parece sujo, além disso, não sei se ValueError
poderia ser criado por algum outro motivo. Eu vim com a seguinte solução baseada em funções geradoras, mas parece um pouco complexa:
thing_index = ( [(i for i in xrange(len(thing_list)) if thing_list[i]==thing)] or [-1] )[0]
Existe uma maneira mais limpa de conseguir a mesma coisa? Vamos supor que a lista não esteja classificada.
thing_index
." - Isso é definitivamente não-pitônico. Passar um valor de token (sem sentido) no caso de uma operação não ser bem-sucedida é desaprovado - as exceções realmente são o caminho certo aqui. Especialmente porquething_list[-1]
é uma expressão válida, significando a última entrada na lista.str.find
método que faz exatamente isso: retorna-1
quando a agulha não é encontrada no assunto.str.index()
lança uma exceção se a string de pesquisa não for encontrada.Respostas:
Não há nada "sujo" em usar a cláusula try-except. Este é o caminho python.
ValueError
será gerado pelo.index
método apenas, porque é o único código que você tem lá!Para responder ao comentário:
Em Python, mais fácil pedir perdão do que obter permissão, a filosofia está bem estabelecida, e não
index
não levantará esse tipo de erro para quaisquer outras questões. Não que eu possa pensar em algum.fonte
{}.get(index, '')
mais pitônico? Já para não falar mais curto mais legível.None
vez de -1 seria bom, mas como você mesmo comentou, str.find () retorna -1 então por que não deveria haver list.find () que faz a mesma coisa? Não estouotherfunction
. Por outro lado, se não quebrou, ...Uma linha. Simples. Sem exceções.
fonte
for
.indexOf = lambda item,list_ : list_.index(item) if item in list_ else -1 # OR None
O
dict
tipo tem umaget
função , onde se a chave não existir no dicionário, o segundo argumento paraget
é o valor que deve retornar. Da mesma forma, hásetdefault
, que retorna o valor emdict
se a chave existir, caso contrário, ele define o valor de acordo com seu parâmetro padrão e retorna seu parâmetro padrão.Você pode estender o
list
tipo para ter umgetindexdefault
método.Que poderia ser usado como:
fonte
Não há nada de errado com o código que usa
ValueError
. Aqui está mais uma linha se você quiser evitar exceções:fonte
next()
função existe no Python 2.6+. Mas é fácil de implementar para 2.5, consulte a implementação da função next () para Python 2.5Esta questão é de filosofia da linguagem. Em Java, por exemplo, sempre houve uma tradição de que as exceções deveriam ser usadas apenas em "circunstâncias excepcionais", ou seja, quando os erros aconteceram, e não para controle de fluxo . No início, isso era por motivos de desempenho, pois as exceções do Java eram lentas, mas agora esse se tornou o estilo aceito.
Em contraste, o Python sempre usou exceções para indicar o fluxo normal do programa, como levantar um,
ValueError
conforme discutimos aqui. Não há nada de "sujo" nisso no estilo Python e há muito mais de onde isso veio. Um exemplo ainda mais comum é aStopIteration
exceção gerada por umnext()
método de iterador para sinalizar que não há mais valores.fonte
StopIteration
porque é claramente definido o que a exceção significa.ValueError
é um pouco genérico demais.Se você faz isso com frequência, é melhor colocá-lo em uma função auxiliar:
fonte
Que tal isso 😃:
fonte
Que tal isso:
Em vez de expor algo tão dependente da implementação, como um índice de lista em uma interface de função, passe a coleção e a coisa e deixe a outra função lidar com os problemas de "teste de associação". Se outra função for escrita para ser agnóstica de tipo de coleção, então provavelmente começaria com:
que funcionará se thing_collection for uma lista, tupla, conjunto ou dicionário.
Isso é possivelmente mais claro do que:
que é o código que você já possui em outra função.
fonte
Que tal assim:
fonte
Tenho o mesmo problema com o método ".index ()" nas listas. Não tenho nenhum problema com o fato de que ele lança uma exceção, mas discordo totalmente do fato de que é um ValueError não descritivo. Eu poderia entender se teria sido um IndexError, no entanto.
Posso ver por que retornar "-1" também seria um problema, porque é um índice válido em Python. Mas, realisticamente, nunca espero que um método ".index ()" retorne um número negativo.
Aqui vai uma linha (ok, é uma linha bastante longa ...), percorre a lista exatamente uma vez e retorna "Nenhum" se o item não for encontrado. Seria trivial reescrever para retornar -1, se você desejar.
Como usar:
fonte
Não sei por que você deve pensar que é sujo ... por causa da exceção? se você quiser um oneliner, aqui está:
mas eu desaconselho o uso; Acho que a solução de Ross Rogers é a melhor, use um objeto para encapsular seu comportamento desejado, não tente levar a linguagem ao seu limite ao custo da legibilidade.
fonte
find()
função e estará tudo limpo;)Eu sugiro:
fonte