ValueErrorを発生させる方法は?


115

文字列内の特定の文字の最大のインデックスを見つけるこのコードがありますが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()ハハハ
slezica

@ user531225:私が削除できるように、別の回答を受け入れてもらえますか。おかげで:)
pyfunc

@ THC4k:奇妙なことに、カウントではなく右端のオカレンスの位置を返します。
John Machin、

@ErikAllik:明らかに彼はそうしました—彼はStackOverflowに投稿しました。それの何がいけないの?
Michael Scheper

回答:


178

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


2
メッセージを使用したくない場合は、raise ValueError代わりに使用できraise ValueError()ます。
Tomasz Gandor

27

これはまだ機能するコードの改訂版であり、さらに、ValueError希望する方法でレイズする方法を示しています。BY-ウェイ、私が思うにfind_last()find_last_index()または何かのsimlarは、この機能のために、より説明的な名前になります。混乱を招く可能性があるのは、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()にすでにa 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番目の機能:OPはforループを必要とする/必要とします。1番目の機能:のFAIL contains('foo', 'f')
John Machin、

1
@John Machin:1つ目の関数で見つかったバグを修正しました。OPの質問またはその下のコメントにforは、回答にループが必要または必要であることを示すものは何もありませんが、たまたま自分のコードに表示されます。とにかく、私の第一の機能を示し、それらをどのように文字がどの見つからない場合、彼らが尋ね。そして、私はのコンテキストで行う方法を説明しました。彼らが何らかの理由でを望んでいるとしても、少なくともいくらか面白くないバージョンが2番目のバージョンに見つかるかもしれません。raiseValueErrorforfor
martineau

「私はforループを使用したい:-)」は、@ pyfuncによって削除された回答に対する初期のコメントでした
John Machin

1
@John Machin:私が見なかった、見られなかった削除された回答のコメントでリクエストを尊重しないことについて、私が責任を負うことはできないと思います。しかし、私の第二の機能は使用していなくてもforループを、それがない方法での実際についての質問どのように答えるつまり、あなたのためにそれをしない何かを呼び出すことによって、 -文字が文字列内に見つからない場合。OPが-fixsやsans- ソリューションを見た後、または後でPythonに慣れた後に何が起きるかを予測する可能性もあります。raiseValueErrorforfor
martineau

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
このコードは質問に答えることがありますが、問題を解決する方法や理由に関する追加のコンテキストを提供すると、回答の長期的な価値が向上します。
ドナルドダック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.