Skip to main content

How to Resolve Python Error "TypeError: string indices must be integers"

The TypeError: string indices must be integers is a common Python error encountered when trying to access characters within a string using indexing or slicing. It specifically means that the value you provided inside the square brackets [] was not an integer (like 0, 1, -1) or a valid slice object (like 0:3), but rather some other incompatible type, most often a string or a tuple.

This guide explains the valid ways to index strings and provides clear solutions to fix this error.

Understanding String Indexing and Slicing​

Python strings are ordered sequences of characters. You can access individual characters or subsequences (slices) using square brackets []:

  • Integer Index: my_string[i] retrieves the single character at the zero-based index i.
    text = "Python"
    print(text[0]) # Output: P
    print(text[2]) # Output: t
    print(text[-1]) # Output: n
  • Slice: my_string[start:stop:step] retrieves a new string containing a sequence of characters.
    text = "Python"
    print(text[0:3]) # Output: Pyt
    print(text[2:]) # Output: thon
    print(text[:4]) # Output: Pyth
    print(text[::2]) # Output: Pto

The TypeError occurs because the value provided inside the [] must be an integer for single character access or a slice object (implicitly created by the start:stop:step syntax) for slicing. Other types, like strings or tuples, are not valid for indexing strings.

Cause 1: Using a Non-Integer (e.g., String) as an Index​

This often happens when a variable intended to hold an integer index actually contains a string representation of that number.

Error Scenario​

message = "Hello"
index_variable = "1" # This holds the string '1', not the integer 1

print(f"Type of index_variable: {type(index_variable)}") # Output: <class 'str'>

try:
# ⛔️ TypeError: string indices must be integers
# Trying to use the string '1' as an index
char = message[index_variable]
print(char)
except TypeError as e:
print(e)

Solution: Convert Index to Integer (int())​

If your index is stored as a string, explicitly convert it to an integer using int() before using it for indexing.

message = "Hello"
index_variable = "1"

# ✅ Convert the string index to an integer
try:
int_index = int(index_variable)
char = message[int_index]
print(f"Character at index {int_index}: '{char}'") # Output: Character at index 1: 'e'
except ValueError:
print(f"Error: Index variable '{index_variable}' cannot be converted to an integer.")
except IndexError:
print(f"Error: Index {int_index} is out of range for '{message}'.")
except TypeError as e: # Should not happen now unless message is not a string
print(f"Unexpected TypeError: {e}")

Always consider adding try...except blocks to handle potential ValueError (if the string isn't a valid integer) and IndexError (if the resulting integer index is out of bounds).

Note on User Input (input())​

The built-in input() function always returns a string, even if the user types digits. You must convert the result of input() to int() if you intend to use it as a numerical index.

message = "Programming"
index_str = input("Enter index to get character: ") # User enters: 3

print(f"Input type: {type(index_str)}") # Output: <class 'str'>

# Incorrect: index_str is '3', not 3
# char = message[index_str] # Raises TypeError

# ✅ Correct: Convert input to int
try:
index_int = int(index_str)
char = message[index_int]
print(f"Character at index {index_int}: '{char}'") # Output: r
except ValueError:
print("Invalid input. Please enter a number.")
except IndexError:
print(f"Index {index_int} is out of range.")

Output:

Enter index to get character: 3
Input type: <class 'str'>
Character at index 3: 'g'

Cause 2: Incorrect Slice Syntax (Using Comma Instead of Colon)​

When trying to slice a string, using a comma , instead of a colon : inside the square brackets creates a tuple, leading to the error.

Error Scenario​

text = "Example"

try:
# ⛔️ TypeError: string indices must be integers or slices, not 'tuple'
# Python interprets [0, 3] as indexing with the tuple (0, 3)
substring = text[0, 3]
print(substring)
except TypeError as e:
print(e)

Solution: Use Colon (:) for Slicing​

Always use colons : to define the start, stop, and step for string slicing.

text = "Example"

# ✅ Correct: Use colon for slicing
substring = text[0:3] # Get characters from index 0 up to (not including) 3
print(f"Slice [0:3]: '{substring}'") # Output: Slice [0:3]: 'Exa'

substring_from_2 = text[2:] # Index 2 to the end
print(f"Slice [2:]: '{substring_from_2}'") # Output: Slice [2:]: 'ample'

Output:

Slice [0:3]: 'Exa'
Slice [2:]: 'ample'

Converting Slice Indices to Integers​

If your slice boundaries (start, stop) are stored as strings (e.g., from user input or file reading), convert them to integers using int() before using them in the slice.

text = "Example"
start_str = "1"
stop_str = "4"

try:
# ✅ Convert string indices to int for slicing
substring = text[int(start_str):int(stop_str)]
print(f"Slice from str indices: '{substring}'") # Output: 'xam'
except ValueError:
print("Error: Slice indices must be convertible to integers.")
except TypeError as e: # Should not happen if text is a string
print(f"Unexpected TypeError: {e}")

Output:

Slice from str indices: 'xam'

Sometimes this TypeError might appear when you mistakenly think you are working with a string, but you actually have a different type.

Trying to Index a JSON String Directly​

If you have data in a JSON string format, you must first parse it into a Python object (like a list or dictionary) using json.loads() before you can index it using Python's rules.

import json

json_string = '["a", "b", "c"]' # A string containing JSON list representation
print(f"Type of json_string: {type(json_string)}") # <class 'str'>

# Incorrect: Trying to index the JSON string directly
# first_char = json_string[0] # This would give '[', not 'a'
# first_element = json_string[1] # This would give '"', not 'a'

# ✅ Correct: Parse JSON first, then index the resulting Python list
my_list = json.loads(json_string)
print(f"Parsed list: {my_list}, Type: {type(my_list)}") # <class 'list'>
first_element = my_list[0]
print(f"First element of parsed list: {first_element}") # Output: a

Output:

Type of json_string: <class 'str'>
Parsed list: ['a', 'b', 'c'], Type: <class 'list'>
First element of parsed list: a

Confusing Strings with Dictionaries​

If you expected a dictionary but have a string, trying to access a "key" using my_string['key'] might look like string indexing, but the real issue is the variable type. You'd typically get a TypeError: string indices must be integers because the key 'key' is not an integer. Solution: Ensure your variable holds a dictionary, not a string, if you intend to use key-based access.

Debugging the Error (type())​

When faced with TypeError: string indices must be integers:

  1. Examine the line number in the traceback.
  2. Look closely at the indexing operation: my_string[...].
  3. Identify the value inside the square brackets (...).
  4. Print its type: print(type(value_inside_brackets)).
  5. This will confirm if it's <class 'str'>, <class 'tuple'>, or another non-integer/non-slice type, explaining the error.
  6. Also, double-check print(type(my_string)) to ensure the variable you're indexing is actually a string and not something else unexpected.

Conclusion​

The TypeError: string indices must be integers (or ...not tuple) clearly states that you've tried to access a position within a string using something other than a valid integer index or a slice.

To fix this:

  1. Ensure indices used for single character access (my_string[index]) are integers. Use int() to convert if necessary (e.g., for user input).
  2. Ensure you use colons (:) to separate start/stop/step values for slicing (my_string[start:stop]), not commas. Convert slice boundaries to int() if they are stored as strings.
  3. Make sure the variable you are indexing is actually a string and not, for example, a JSON string that needs parsing or a different data type altogether.

By using integer indices and correct slice syntax, you can reliably access parts of your Python strings.