จะเพิ่ม 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-the-วิธีที่ผมคิดว่า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()คือ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วนซ้ำในคำตอบแม้ว่าจะมีคำถามปรากฏในโค้ดของพวกเขาเองก็ตาม ทั้งนี้ที่ 1 แสดงให้เห็นว่าการทำงานของฉันให้รู้ว่าจะเมื่อตัวละครไม่พบซึ่งเป็นสิ่งที่พวกเขาถาม และฉันได้แสดงวิธีการทำในบริบทของไฟล์. แม้ว่าพวกเขาจะต้องการเหตุผลบางอย่าง แต่ฉันคิดว่าคนอื่น ๆ อาจพบว่ารุ่นที่ 2 โดยที่อย่างน้อยก็ค่อนข้างน่าสนใจ raiseValueErrorforfor
martineau

"ฉันต้องการใช้สำหรับการวนซ้ำ :-)" เป็นความคิดเห็นเบื้องต้นของคำตอบที่ถูกลบไปแล้วโดย @pyfunc
John Machin

1
@ John Machin: อย่าคิดว่าฉันจะต้องรับผิดชอบต่อการไม่เคารพคำขอในความคิดเห็นของคำตอบที่ถูกลบที่ฉันไม่ได้เห็นและมองไม่เห็น อย่างไรก็ตามแม้ว่าฟังก์ชั่นที่ 2 ของฉันไม่ได้ใช้forห่วงมันไม่ในทางตอบคำถามที่เกิดขึ้นจริงเกี่ยวกับวิธีการเมื่อตัวละครไม่พบในสตริง - คือโดยการเรียกอย่างอื่นที่ไม่ได้สำหรับคุณ นอกจากนี้ยังมีความเป็นไปได้ที่ OP อาจเอาชนะ-fixation หรืออะไรก็ได้หลังจากเห็น 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
แม้ว่ารหัสนี้อาจตอบคำถามได้ แต่การให้บริบทเพิ่มเติมเกี่ยวกับวิธีการและ / หรือเหตุผลในการแก้ปัญหาจะช่วยเพิ่มมูลค่าในระยะยาวของคำตอบ
Donald Duck
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.