这是您的代码的修订版本,它仍然有效,并且说明了如何以您想要的方式提出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'
更新——更简单的方法
哇!这是一个更简洁的版本 - 基本上是单行 - 这也可能更快,因为它在向前搜索 first 匹配字符之前反转(通过[::-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