Como aumentar um ValueError?

115

Eu tenho este código que encontra o maior índice de um caractere específico em uma string, no entanto, gostaria que gerasse um ValueErrorquando o caractere especificado não ocorrer em uma string.

Então, algo assim:

contains('bababa', 'k')

resultaria em:

ValueError: could not find k in bababa

Como posso fazer isso?

Este é o código atual para minha função:

def contains(string,char):
  list = []

  for i in range(0,len(string)):
      if string[i] == char:
           list = list + [i]

  return list[-1]
user531225
fonte

Respostas:

178

raise ValueError('could not find %c in %s' % (ch,str))

NPE
fonte
27

Aqui está uma versão revisada do seu código que ainda funciona e ilustra como criar um ValueErrorda maneira que você deseja. A propósito, eu acho find_last(), find_last_index()ou algo semelhante seria um nome mais descritivo para esta função. Para aumentar a confusão possível, está o fato de que o Python já tem um método de objeto recipiente denominado __contains__()que faz algo um pouco diferente, em termos de teste de associação.

def contains(char_string, char):
    largest_index = -1
    for i, ch in enumerate(char_string):
        if ch == char:
            largest_index = i
    if largest_index > -1:  # any found?
        return largest_index  # return index of last one
    else:
        raise ValueError('could not find {!r} in {!r}'.format(char, char_string))

print(contains('mississippi', 's'))  # -> 6
print(contains('bababa', 'k'))  # ->
Traceback (most recent call last):
  File "how-to-raise-a-valueerror.py", line 15, in <module>
    print(contains('bababa', 'k'))
  File "how-to-raise-a-valueerror.py", line 12, in contains
    raise ValueError('could not find {} in {}'.format(char, char_string))
ValueError: could not find 'k' in 'bababa'

Atualizar - uma maneira substancialmente mais simples

Uau! Aqui está uma versão muito mais concisa - essencialmente de uma linha - que também é provavelmente mais rápida porque inverte (via [::-1]) a string antes de fazer uma busca direta através dela para o primeiro caractere correspondente e faz isso usando o index()método de string embutido rápido . Com relação à sua pergunta real, um pequeno bônus de conveniência que vem com o uso index()é que ele já levanta um ValueErrorquando a substring de caractere não é encontrada, então nada adicional é necessário para fazer isso acontecer.

Aqui está, junto com um teste de unidade rápido:

def contains(char_string, char):
    #  Ending - 1 adjusts returned index to account for searching in reverse.
    return len(char_string) - char_string[::-1].index(char) - 1

print(contains('mississippi', 's'))  # -> 6
print(contains('bababa', 'k'))  # ->
Traceback (most recent call last):
  File "better-way-to-raise-a-valueerror.py", line 9, in <module>
    print(contains('bababa', 'k'))
  File "better-way-to-raise-a-valueerror", line 6, in contains
    return len(char_string) - char_string[::-1].index(char) - 1
ValueError: substring not found
martineau
fonte
12
>>> def contains(string, char):
...     for i in xrange(len(string) - 1, -1, -1):
...         if string[i] == char:
...             return i
...     raise ValueError("could not find %r in %r" % (char, string))
...
>>> contains('bababa', 'k')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in contains
ValueError: could not find 'k' in 'bababa'
>>> contains('bababa', 'a')
5
>>> contains('bababa', 'b')
4
>>> contains('xbababa', 'x')
0
>>>
John Machin
fonte
4
>>> response='bababa'
...  if "K" in response.text:
...     raise ValueError("Not found")
Kaushik Dey
fonte