Wie kann ein ValueError ausgelöst werden?


115

Ich habe diesen Code, der den größten Index eines bestimmten Zeichens in einer Zeichenfolge findet. Ich möchte jedoch, dass ein a ausgelöst wird, ValueErrorwenn das angegebene Zeichen in einer Zeichenfolge nicht vorkommt.

Also so etwas wie das:

contains('bababa', 'k')

würde zu einem führen:

ValueError: could not find k in bababa

Wie kann ich das machen?

Hier ist der aktuelle Code für meine Funktion:

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

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

  return list[-1]

5
Erhöhen Sie einfach ValueError () hahaha
slezica

@ user531225: Kannst du eine andere Antwort akzeptieren, damit ich meine löschen kann? Danke :)
Pyfunc

@ THC4k: So seltsam, dass es die Position des am weitesten rechts stehenden Ereignisses anstelle der Zählung zurückgibt.
John Machin

@ErikAllik: Offensichtlich hat er das getan - er hat auf StackOverflow gepostet. Was stimmt damit nicht?
Michael Scheper

Antworten:


178

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


2
Wussten Sie, dass Sie, wenn Sie die Nachricht nicht verwenden möchten, dies raise ValueErrorstattdessen tun können raise ValueError()?
Tomasz Gandor

27

Hier ist eine überarbeitete Version Ihres Codes, die immer noch funktioniert. Außerdem wird veranschaulicht, wie Sie einen Code nach Ihren Wünschen erstellen können ValueError. By-the-Art und Weise, denke ich find_last(), find_last_index()oder würde etwas simlar ein beschreibender Name für diese Funktion. Zu der möglichen Verwirrung trägt die Tatsache bei, dass Python bereits über eine Containerobjektmethode mit dem Namen verfügt __contains__(), die in Bezug auf Mitgliedschaftstests etwas anderes bewirkt.

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'

Update - Ein wesentlich einfacherer Weg

Beeindruckend! Hier ist eine viel prägnante versions im Wesentlichen eines Einzeiler-die auch wahrscheinlich schneller ist , weil es umkehrt (über [::-1]) die Zeichenfolge , bevor sie eine Vorwärtssuche durch sie für den tut ersten Anpassungs Charakter und es ist mit so schnellen integrierten String - index()Methode . In Bezug auf Ihre eigentliche Frage besteht ein netter kleiner Bonus, der mit der Verwendung einhergeht index(), darin, dass bereits ein ValueErrorFehler ausgelöst wird, wenn der Zeichensubstring nicht gefunden wird. Daher ist nichts Zusätzliches erforderlich, um dies zu erreichen.

Hier ist es zusammen mit einem schnellen Unit-Test:

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. Funktion: Das OP braucht / will eine forSchleife. 1. Funktion: FAIL für contains('foo', 'f').
John Machin

1
@ John Machin: Fehler behoben, den Sie in der 1. Funktion gefunden haben, danke, dass Sie mich darauf aufmerksam gemacht haben. Ich sehe in der Frage des OP oder in den Kommentaren darunter nichts, was darauf hinweist, dass sie eine forSchleife in einer Antwort benötigen oder wollen , obwohl eine zufällig in ihrem eigenen Code erscheint. Wie auch immer, meine erste Funktion zeigt ihnen, wie man raiseeinen ValueErrorCharakter findet, wenn er nicht gefunden wird . und ich habe gezeigt, wie man im Kontext von a for. Selbst wenn sie foraus irgendeinem Grund eine wollen , denke ich, dass andere die 2. Version ohne eine zumindest etwas interessant finden könnten.
Martineau

"Ich möchte for loop verwenden :-)" war ein früher Kommentar zu der jetzt gelöschten Antwort von @pyfunc
John Machin

1
@ John Machin: Glaube nicht, dass ich dafür verantwortlich gemacht werden kann, dass ich Anfragen in Kommentaren gelöschter Antworten, die ich nicht gesehen habe und die ich nicht sehen kann, nicht berücksichtigt habe. Doch obwohl meine zweite Funktion nicht nicht verwendet forSchleife, es ist in einer Art und Weise beantwortet die eigentliche Frage , wie man raiseein , ValueErrorwenn das Zeichen nicht im String gefunden wird - nämlich durch etwas anderes fordert , dass es für Dich tut. Es besteht auch die Möglichkeit, dass das OP seine forFixierung oder was auch immer überwindet, nachdem es eine Sans- forLösung gesehen oder sich später mit Python vertraut gemacht hat.
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
Während dieser Code die Frage möglicherweise beantwortet, würde die Bereitstellung eines zusätzlichen Kontexts darüber, wie und / oder warum das Problem gelöst wird, den langfristigen Wert der Antwort verbessern.
Donald Duck
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.