Як підняти ValueError?


115

У мене є цей код, який знаходить найбільший індекс конкретного символу в рядку, проте я хотів би, щоб він підняв a, ValueErrorколи вказаний символ не зустрічається в рядку.

Тож щось подібне:

contains('bababa', 'k')

призведе до:

ValueError: could not find k in bababa

Як я можу це зробити?

Ось поточний код для моєї функції:

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

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

  return list[-1]

5
Просто так підніміть ValueError () hahaha
slezica

@ user531225: Чи можете ви прийняти якусь іншу відповідь, щоб я могла видалити свою. Дякую :)
pyfunc

@ THC4k: Настільки дивно, що він повертає позицію крайньої правої зустрічі замість підрахунку.
Джон Махін

@ErikAllik: Очевидно, що він зробив - він опублікував у StackOverflow. Що з цим?
Майкл Шепер

Відповіді:


178

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


2
Чи знали ви, що, якщо ви не хочете використовувати повідомлення, можете просто raise ValueErrorзамість цього raise ValueError()?
Томаш

27

Ось переглянута версія вашого коду, яка все ще працює, плюс вона пояснює, як підняти ValueErrorпотрібний спосіб. Зрозуміло , я думаю find_last(), find_last_index()або щось подібне було б більш описовою назвою для цієї функції. Додавання можливої ​​плутанини полягає в тому, що Python вже має метод об'єкта контейнера, який називається __contains__()дещо іншим, тестуючим членство.

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'

Оновлення - істотно простіший спосіб

Оце Так! Ось набагато більш лаконічна версія - по суті, однолінійна - що також швидше, тому що вона обертає (через [::-1]) рядок перед тим, як здійснити пошук вперед вперед для першого символу, що відповідає, і це робить за допомогою швидкого вбудованого рядкового index()методу . Що стосується Вашого актуального питання, приємним невеликим бонусним зручністю, яке постає при використанні, index()є те, що воно вже викликає, ValueErrorколи символьна підрядка не знайдена, тому нічого додаткового не потрібно, щоб це відбулося.

Ось він разом із швидким тестовим блоком:

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

2-а функція: ОП потребує / хоче forцикл. 1-а функція: FAIL for contains('foo', 'f').
Джон Махін

1
@John Machin: Виправлена ​​помилка, яку ви знайшли в першій функції, дякую, що ви звернули її на мою увагу. Я не бачу нічого в питанні ОП або коментарях під ним, що вказує, що вони потребують або хочуть forциклу у відповіді, хоча це трапляється у власному коді. Так чи інакше мої 1 - функція показує їм , як , коли символ не найден , який є те , що вони просили. і я проілюстрував, як це робити в контексті . Навіть якщо вони хочуть чомусь, я думаю, що інші можуть знайти другу версію без однієї хоча б дещо цікавої. raiseValueErrorforfor
мартіно

"Я хочу використовувати для циклу :-)" - це був ранній коментар до вже видаленої відповіді від @pyfunc
Джон Макін

1
@John Machin: Не думаю, що я можу нести відповідальність за невиконання запитів у коментарях видалених відповідей, яких я не бачив і не бачу. Тим НЕ менше, навіть якщо моя друга функція не використовує forцикл, він робить таким чином відповісти на актуальне питання про те , як до , коли символ не знайдений в рядку , а саме - по телефону що - то ще , що робить це для вас. Існує також ймовірність того, що ОП може перебороти їхнє виправлення чи що завгодно, після того, як побачать рішення без скантування чи пізніше ознайомлення з Python. raiseValueErrorforfor
мартіно

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

4
>>> response='bababa'
...  if "K" in response.text:
...     raise ValueError("Not found")

1
Хоча цей код може відповісти на питання, надаючи додатковий контекст щодо того, як та / або чому він вирішує проблему, покращить довгострокове значення відповіді.
Дональд Дак
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.