Skip to main content

How to Resolve Python "TypeError with List/Tuple/Slice Indices Must be Integers

Python sequences like lists, tuples, and strings allow you to access individual elements or sub-sequences (slices) using square bracket notation ([]). However, this indexing and slicing mechanism strictly requires integer values (or slice objects). If you attempt to use a different data type, such as a string or a float, as an index or within a slice, Python will raise a TypeError, commonly:

  • TypeError: list indices must be integers or slices, not str
  • TypeError: tuple indices must be integers or slices, not str
  • TypeError: slice indices must be integers or None or have an __index__ method

This guide explains why these errors occur and provides the standard solutions, primarily involving ensuring your indices are integers.

Understanding the Error: Indexing/Slicing Requires Integers

Python's sequences (list, tuple, str) are ordered collections where elements are accessed based on their numerical position (index).

  • Indexing: my_sequence[i] retrieves the single element at position i.
  • Slicing: my_sequence[start:stop:step] extracts a sub-sequence.

Both i in indexing and the start, stop, and step values in slicing must be integers (or None for start/stop in slices, or objects implementing the special __index__ method). Providing a value of a different type, like a string '1' or a float 1.0, violates this requirement. Dictionaries are different; they use keys (which can be various hashable types, often strings) for access, not numerical indices.

Error 1: list/tuple indices must be integers or slices, not str

This error occurs when you try to access an element of a list or tuple using my_sequence[some_string] instead of my_sequence[some_integer].

Cause: Using a String as an Index

You provided a string value inside the square brackets where an integer representing the position was expected.

my_list = ['apple', 'banana', 'cherry']
index_as_string = '1' # String containing a digit

# Error Scenario
try:
# ⛔️ TypeError: list indices must be integers or slices, not str
# Trying to use the string '1' as an index
value = my_list[index_as_string]
print(value)
except TypeError as e:
print(e)

Even though the string '1' looks like a number, Python treats it as a distinct string type, which is invalid for list/tuple indexing.

Solution: Convert String Index to int()

If the string variable contains a valid representation of an integer, use the int() constructor to convert it before using it as an index.

my_list = ['apple', 'banana', 'cherry']
index_as_string = '1'

# Convert the string index to an integer
index_as_int = int(index_as_string)
print(f"Index as integer: {index_as_int} (Type: {type(index_as_int)})")

# Use the integer index for access
value = my_list[index_as_int]
print(f"Element at index {index_as_int}: '{value}'")

# Direct conversion in the index access:
value_direct = my_list[int(index_as_string)]
print(f"Element at index {index_as_int} (direct): '{value_direct}'")

Output:

Index as integer: 1 (Type: <class 'int'>)
Element at index 1: 'banana'
Element at index 1 (direct): 'banana'
note

int() will raise a ValueError if the string cannot be converted to an integer (e.g., int('hello') or int('1.5')).

Special Case: User Input

Remember that Python's input() function always returns a string, even if the user types numbers. You must convert user input intended as an index to an integer.

my_list = ['first', 'second', 'third']
index_input = input("Enter index (0-2): ")
print(f"Input type: {type(index_input)}")

# Error without conversion
try:
value = my_list[index_input] # ⛔️ TypeError: list indices must be integers...
except TypeError as e:
print(f"Error without conversion: {e}")

# ✅ Corrected: Convert input to int
try:
index_num = int(index_input)
value = my_list[index_num]
print(f"Value at index {index_num}: '{value}'")
except ValueError:
print("Invalid input: Please enter a number.")
except IndexError:
print(f"Invalid index: Index {index_num} is out of range.")

Output:

Enter index (0-2): 2
Input type: <class 'str'>
Error without conversion: list indices must be integers or slices, not str
Value at index 2: 'third'

Reminder: Accessing Dictionaries (Uses Keys)

If you intended to access data by a name (like 'name' or 'age'), you likely meant to use a dictionary ({}), which uses keys (often strings) within the square brackets, not a list or tuple.

# This is a LIST, accessed by integer index
my_list = ['Anna', 23]
print(my_list[0]) # Output: Anna

# This is a DICTIONARY, accessed by string key
my_dict = {'name': 'Anna', 'age': 23}
print(my_dict['name']) # Output: Anna

Ensure you are using the correct data structure for your access method.

Error 2: slice indices must be integers or None or have an __index__ method

This specific TypeError occurs when you use slicing notation (start:stop:step) but provide a non-integer (most commonly a float) for any of the start, stop, or step values.

Cause: Using Floats (or other non-ints) in Slices

The indices defining the start, end, and step of a slice must be integers or None. Floats are not allowed.

my_string = "abcdefgh"
start_float = 1.0
end_float = 5.5

# Error Scenario
try:
# ⛔️ TypeError: slice indices must be integers or None or have an __index__ method
# Using floats 1.0 and 5.5 for start/stop indices
substring = my_string[start_float:end_float]
print(substring)
except TypeError as e:
print(e)

Solution: Convert Slice Values to int()

Convert any float values used for slicing to integers using int(). Remember that int() truncates (rounds down towards zero).

my_string = "abcdefgh"
start_float = 1.0
end_float = 5.5

# Convert float indices to integers before slicing
start_int = int(start_float) # Becomes 1
end_int = int(end_float) # Becomes 5
print(f"Converting slice indices: int({start_float}) -> {start_int}, int({end_float}) -> {end_int}")

# Slice using the integer indices
substring = my_string[start_int:end_int] # Equivalent to my_string[1:5]

print(f"Original string: '{my_string}'")
print(f"Substring sliced with ints [{start_int}:{end_int}]: '{substring}'")

Output:

Converting slice indices: int(1.0) -> 1, int(5.5) -> 5
Original string: 'abcdefgh'
Substring sliced with ints [1:5]: 'bcde'

Note on Division Results (/ vs. //)

This error often occurs when calculating slice indices using standard division (/), which always returns a float in Python 3, even if the result is mathematically a whole number (e.g., 10 / 2 is 5.0).

my_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
midpoint_float = len(my_list) / 2 # Result is 5.0 (a float)

try:
# ⛔️ TypeError: slice indices must be integers...
first_half = my_list[:midpoint_float]
print(first_half)
except TypeError as e:
print(f"Error with float index from division: {e}")

# Solution 1: Use integer division //
midpoint_int = len(my_list) // 2 # Result is 5 (an int)
first_half_fixed1 = my_list[:midpoint_int]
print(f"\nFirst half (using //): {first_half_fixed1}") # Output: [0, 1, 2, 3, 4]

# Solution 2: Convert result of / to int()
first_half_fixed2 = my_list[:int(midpoint_float)]
print(f"First half (using int()): {first_half_fixed2}") # Output: [0, 1, 2, 3, 4]

Output:

Error with float index from division: slice indices must be integers or None or have an __index__ method

First half (using //): [0, 1, 2, 3, 4]
First half (using int()): [0, 1, 2, 3, 4]
note

Use integer division (//) or explicitly convert results to int() when calculating slice indices.

Debugging: Checking Variable Types

If you are unsure what type your index or slice variable holds, use type():

index_variable = '2' # Example string index

print(f"Variable: {index_variable}, Type: {type(index_variable)}")
# Output: Variable: 2, Type: <class 'str'> -> Needs conversion!

slice_variable = 10 / 2 # Example float slice index
print(f"Variable: {slice_variable}, Type: {type(slice_variable)}")
# Output: Variable: 5.0, Type: <class 'float'> -> Needs conversion!

Output:

Variable: 2, Type: <class 'str'>
Variable: 5.0, Type: <class 'float'>

Conclusion

The TypeError indicating that list, tuple, or slice indices must be integers (or None for slices) arises when you attempt to use a non-integer type like str or float within the square brackets [] for indexing or slicing.

To fix these errors:

  1. For indexing (my_list[index]): Ensure the index is an integer. If it's a numeric string (e.g., from input()), convert it using int(index). If you intended key-based access, use a dictionary instead of a list/tuple.
  2. For slicing (my_list[start:stop:step]): Ensure start, stop, and step are integers or None. Convert any float values (often resulting from / division) using int(), or use integer division (//) when calculating indices.

Always use integers for positional access within sequences.