Skip to main content

How to Solve "ValueError: substring not found" in Python with str.index()

The str.index() method in Python is used to find the index of a substring within a string. However, if the substring is not found, it raises a ValueError: substring not found.

This guide explains how to avoid this error using safer alternatives like str.find(), the in operator, and, when appropriate, try-except blocks.

Understanding the ValueError with str.index()

The str.index() method is designed to raise a ValueError if the substring isn't found:

my_str = 'tutorialreference'

# ⛔️ ValueError: substring not found
# idx = my_str.index('z') # This line would cause the error

This behavior is different from the related str.find() method, which we'll discuss next.

The str.find() method is almost identical to str.index(), but instead of raising an exception when the substring isn't found, it returns -1. This makes it much safer to use in many cases:

my_str = 'tutorialreference'
index = my_str.find('z')

print(index) # Output: -1

if index != -1:
print(my_str[index])
else:
print('The character is not contained in the string')

# Output: The character is not contained in the string
  • my_str.find('z'): Searches for 'z' within my_str.
  • if index != -1:: Checks if the substring was found (any index other than -1). This is the standard pattern when using find().

Using the in Operator for Substring Checks

If you only need to know if a substring is present (and don't need its index), the in operator is the most Pythonic and readable approach:

my_str = 'tutorialreference'

if 'z' in my_str:
# This won't execute since `z` not in `my_str`.
idx = my_str.index('z') # If this block executed it would raise an exception.
print(idx)
else:
print('The substring is not contained in the string')
# Output: The substring is not contained in the string
  • 'z' in my_str: This directly checks if the substring 'z' is present within my_str. It's clear, concise, and doesn't raise an exception. Use this if you don't need the index.

Handling ValueError with try-except (Situational)

While find() and in are generally better, you can use a try-except block to handle the ValueError:

my_str = 'tutorialreference'

try:
idx = my_str.index('z')
print(idx)
except ValueError:
print('The substring is not contained in the string')

# Output: The substring is not contained in the string
  • This approach is less readable and less efficient than using find() or in.
  • The try-except block is more appropriate for handling unexpected errors, not for situations where you can easily check beforehand.

To perform a case-insensitive search with any of these methods, convert both the string and the substring to lowercase (or uppercase):

my_str = 'tutorialreference'
test_char = 't'
index = my_str.lower().index(test_char.lower()) # Convert to lowercase for comparison
print(index) # Output: 0
  • The lower() is used on both strings to perform the comparison in a case insensitive way.

  • Checking startswith() and endswith()

If you only need to check if a string starts or ends with a specific substring, use the startswith() and endswith() methods:

my_str = 'tutorialreference'

if my_str.startswith('t'):
print('The string starts with the substring') # Output: The string starts with the substring
else:
print('The string does not start with the substring')

if my_str.endswith('e'):
print('The string ends with the substring') # Output: The string ends with the substring
else:
print('The string does not end with the substring')
  • These methods will check if the string begins or ends with a specific character or a sequence of characters.

Conclusion

This guide explained how to deal with the ValueError: substring not found error when using the index() method with strings.

  • The find() method is best when used to avoid the ValueError when looking for a substring within a string.
  • Alternatively, the in operator can be used to determine if a string contains a substring.

Use the method that is best for your needs to ensure your programs will run without problems.