TypeError: list indices must be integers or slices, not str

avatar
Borislav Hadzhiev

Last updated: Apr 8, 2024
9 min

banner

# Table of Contents

  1. TypeError: LIST indices must be integers or slices, not str
  2. TypeError: TUPLE indices must be integers or slices, not str
  3. TypeError: SLICE indices must be integers or None or have an __index__ method

# TypeError: list indices must be integers or slices, not str

The Python "TypeError: list indices must be integers or slices, not str" occurs when we use a string instead of an integer to access a list at a specific index.

To solve the error, use the int() class to convert the string to an integer, e.g. my_list[int(my_str)].

typeerror list indices must be integers or slices not str

Here is an example of how the error occurs.

main.py
my_str = '1' my_list = ['a', 'b', 'c'] # ⛔️ TypeError: list indices must be integers or slices, not str result = my_list[my_str]

The error is caused because we are using a string as a list index.

main.py
a_list = ['a', 'b', 'c', 'd', 'e'] # ✅ Indices must be integers print(a_list[0]) # 👉️ 'a' print(a_list[1]) # 👉️ 'b'

# Use an integer or a slice for list indices

To solve the error, use an integer or a slice for list indices.

main.py
my_str = '1' my_list = ['a', 'b', 'c'] # ✅ Convert str to int result = my_list[int(my_str)] print(result) # 👉️ 'b'

We used the int() class to convert the string to an integer to be able to access the list at an index.

Python indexes are zero-based, so the first item in a list has an index of 0, and the last item has an index of -1 or len(a_list) - 1.

You also need to convert the indices to integers if you need to get a slice of a list.

main.py
start_index = '0' stop_index = '2' a_list = ['a', 'b', 'c', 'd', 'e'] new_list = a_list[int(start_index):int(stop_index)] print(new_list) # 👉️ ['a', 'b']

Notice that we used the int() class to convert both values to integers.

The syntax for list slicing is a_list[start:stop:step].

main.py
a_list = ['a', 'b', 'c', 'd', 'e'] print(a_list[0:2]) # 👉️ ['a', 'b'] print(a_list[1:3]) # 👉️ ['b', 'c']

The start index is inclusive and the stop index is exclusive (up to, but not including).

If you need to iterate over a list with access to the index of the current iteration, use enumerate().

main.py
my_list = ['bobby', 'hadz', 'com'] for index, item in enumerate(my_list): print(index, item) # 👉️ 0 bobby, 1 hadz, 2 com

The enumerate() function takes an iterable and returns an enumerate object containing tuples where the first element is the index and the second is the corresponding item.

You can also use the range() class to get access to the index.

main.py
my_list = ['bobby', 'hadz', 'com'] for index in range(len(my_list)): # 0 bobby # 1 hadz # 2 com print(index, my_list[index])

# Checking if an item is in a List

If you need to check if a value is in a list, use the in operator.

main.py
a_list = ['a', 'b', 'c'] if 'a' in a_list: # 👇️ this runs print('The value is in the list') else: print('The value is not in the list') print('a' in a_list) # 👉️ True print('Z' in a_list) # 👉️ False

The in operator returns True if the value is in the list and false otherwise.

# The input() function always returns a string

Note that the input() function always returns a string even if the user enters an integer.

main.py
a_list = ['a', 'b', 'c', 'd'] index = input('Enter an index: ') print(index) # 👉️ '1' print(type(index)) # 👉️ string # ⛔️ TypeError: list indices must be integers or slices, not str print(a_list[index])

input always returns string

The input() function converts the supplied value to a string and returns it.

To solve the error, use the int() class to convert the value to an integer before accessing the list.

main.py
a_list = ['a', 'b', 'c', 'd'] # ✅ Convert to integer index = int(input('Enter an index: ')) print(index) # 👉️ 1 print(type(index)) # 👉️ <class 'int'> print(a_list[index]) # 👉️ b

convert input to integer

# Working with a list of dictionaries or lists of dictionaries

If you meant to declare a dictionary, make sure to use curly braces (not square brackets).

main.py
my_dict = {} my_dict['name'] = 'Bobby Hadz' my_dict['age'] = 30 print(my_dict) # 👉️ {'name': 'Bobby Hadz', 'age': 30}

If you are iterating over a list of dictionaries, make sure to access key-value pairs of the dictionary on each iteration.

main.py
my_list = [ {'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}, {'id': 3, 'name': 'Carl'}, ] for entry in my_list: print(f'Employee id: {entry["id"]}') print(f'Employee name: {entry["name"]}')

We used a for loop to iterate over a list of dictionaries.

The entry variable stores a dictionary on each iteration, so you can access it at a specific key to get the corresponding value.

If you need to access the index of the current iteration, use the enumerate() function.

main.py
my_list = [ {'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}, {'id': 3, 'name': 'Carl'}, ] for index, dictionary in enumerate(my_list): print(index, dictionary) print(dictionary['id'], dictionary['name'])

You can use an index to access a specific dictionary in the list and then access a key in the dictionary.

main.py
my_list = [ {'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}, {'id': 3, 'name': 'Carl'}, ] result = my_list[0]['name'] print(result) # 👉️ 'Alice'

We access the list item at index 0 and then access the name key of the dictionary.

# Getting the index of a List value

Use the list.index() method if you need to get the index of a value in a list.

main.py
a_list = ['a', 'b', 'c'] print(a_list.index('a')) # 👉️ 0 print(a_list.index('b')) # 👉️ 1

The list.index() method returns the index of the first item whose value is equal to the provided argument.

# Working with a dictionary with a list value

If you have a dictionary with a list value, access the specific key before accessing an index.

main.py
my_dict = { 'fruits': ['apple', 'banana', 'kiwi'] } result = my_dict['fruits'][0] print(result) # 👉️ 'apple'

If you need to iterate over a dictionary, use the dict.items() method.

main.py
my_dict = {'name': 'Alice', 'age': 30} for key, value in my_dict.items(): print(key, value) # 👉️ name Alice, age 30

The dict.items method returns a new view of the dictionary's items ((key, value) pairs).

# Parse JSON string to native Python objects before accessing them

If you get the error when working with a JSON string, make sure to parse the JSON into a native Python object before accessing specific items.

main.py
import json my_json = json.dumps( [ {'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}, {'id': 3, 'name': 'Carl'}, ] ) print(type(my_json)) # 👉️ <class 'str'> # ✅ convert to native Python object my_list = json.loads(my_json) print(my_list[0]['name']) # 👉️ 'Alice' print(my_list[1]['name']) # 👉️ 'Bob' print(type(my_list)) # 👉️ <class 'list'>

The json.loads method parses a JSON string into a native Python object.

Conversely, the json.dumps method converts a Python object to a JSON formatted string.

You can then use integers for list indexes or strings to access a key in a dictionary.

# Checking what type of object a variable stores

If you aren't sure what type of object a variable stores, use the type() class.

main.py
my_dict = {'name': 'Alice', 'age': 30} print(type(my_dict)) # 👉️ <class 'dict'> print(isinstance(my_dict, dict)) # 👉️ True my_list = ['a', 'b', 'c'] print(type(my_list)) # 👉️ <class 'list'> print(isinstance(my_list, list)) # 👉️ True

The type class returns the type of an object.

The isinstance function returns True if the passed-in object is an instance or a subclass of the passed-in class.

# Table of Contents

  1. TypeError: TUPLE indices must be integers or slices, not str
  2. TypeError: SLICE indices must be integers or None or have an __index__ method

# TypeError: tuple indices must be integers or slices, not str

The Python "TypeError: tuple indices must be integers or slices, not str" occurs when we use a string instead of an integer to access a tuple at a specific index.

To solve the error, use the int() class to convert the string to an integer.

typeerror tuple indices must be integers or slices not str

Here is an example of how the error occurs.

main.py
my_tuple = ('a', 'b', 'c') my_str = '1' # ⛔️ TypeError: tuple indices must be integers or slices, not str result = my_tuple[my_str]

The error is caused because we are using a string as a tuple index.

main.py
my_tuple = ('a', 'b', 'c', 'd') # ✅ indices must be integers print(my_tuple[0]) # 👉️ a print(my_tuple[1]) # 👉️ b print(my_tuple[1:3]) # 👉️ ('b', 'c')

# Use an integer or a slice when accessing the tuple

To solve the error, convert the string to an integer using the int() class.

main.py
my_tuple = ('a', 'b', 'c') my_str = '1' # ✅ convert str to int result = my_tuple[int(my_str)] print(result) # 👉️ 'b'

The code sample uses the int() class to convert the string index to an integer when accessing the tuple.

Python indexes are zero-based, so the first item in a tuple has an index of 0, and the last item has an index of `-1` or len(my_tuple) - 1.

If you need to get a slice of a tuple, both indices must be integers.

main.py
my_tuple = ('a', 'b', 'c', 'd') start_index = '1' stop_index = '3' new_tuple = my_tuple[int(start_index):int(stop_index)] print(new_tuple) # 👉️ ('b', 'c')

The syntax for tuple slicing is my_tuple[start:stop:step].

main.py
my_tuple = ('a', 'b', 'c', 'd') print(my_tuple[0:2]) # 👉️ ('a', 'b') print(my_tuple[1:3]) # 👉️ ('b', 'c')

The start index is inclusive and the stop index is exclusive (up to, but not including).

If the start index is omitted, it is considered to be 0, if the stop index is omitted, the slice goes to the end of the tuple.

# Iterating over a tuple

You can use a simple for loop to iterate over a tuple.

main.py
my_tuple = ('a', 'b', 'c', 'd') for item in my_tuple: print(item) # 👉️ a, b, c, d

If you need to get access to the index of the current iteration, use the enumerate() function.

main.py
my_tuple = ('a', 'b', 'c') for index, item in enumerate(my_tuple): # 0 a # 1 b # 2 c print(index, item)

# Checking if an item is in a tuple

If you need to check if an item is in a tuple, use the in operator.

main.py
my_tuple = ('a', 'b', 'c') print('a' in my_tuple) # 👉️ True print('hello' in my_tuple) # 👉️ False

The in operator returns True if the item is in the tuple and False otherwise.

# Working with dictionaries and tuples

If you meant to declare a dictionary, make sure to use curly braces (not parentheses).

main.py
my_dict = {} my_dict['name'] = 'Alice' my_dict['age'] = 30 print(my_dict) # 👉️ {'name': 'Alice', 'age': 30}

If you are iterating over a tuple of dictionaries, make sure to access key-value pairs of the dictionary on each iteration.

main.py
my_tuple = ( {'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}, {'id': 3, 'name': 'Carl'}, ) for entry in my_tuple: print(entry['id']) print(entry['name'])

We used a for loop to iterate over a tuple of dictionaries.

The entry variable stores a dictionary on each iteration, so you can access it at a specific key to get the corresponding value.

You can use an index to access a specific dictionary in the tuple and then access a key in the dictionary.

main.py
my_tuple = ( {'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}, {'id': 3, 'name': 'Carl'}, ) result = my_tuple[0]['name'] print(result) # 👉️ 'Alice'

We access the tuple item at index 0 and then access the name key of the dictionary.

If you have a dictionary with a tuple value, access the specific key before accessing an index.

main.py
my_dict = { 'fruits': ('apple', 'banana', 'kiwi') } result = my_dict['fruits'][0] print(result) # 👉️ 'apple'

If you need to iterate over a dictionary, use the dict.items() method.

main.py
my_dict = {'name': 'Alice', 'age': 30} for key, value in my_dict.items(): print(key, value) # 👉️ name Alice, age 30

The dict.items() method returns a new view of the dictionary's items ((key, value) pairs).

# How tuples are constructed in Python

In case you declared a tuple by mistake, tuples are constructed in multiple ways:

  • Using a pair of parentheses () creates an empty tuple
  • Using a trailing comma - a, or (a,)
  • Separating items with commas - a, b or (a, b)
  • Using the tuple() constructor
Tuples are very similar to lists, but implement fewer built-in methods and are immutable (cannot be changed).

If you aren't sure what type of object a variable stores, use the type() class.

main.py
my_tuple = ('a', 'b', 'c') print(type(my_tuple)) # 👉️ <class 'tuple'> print(isinstance(my_tuple, tuple)) # 👉️ True my_list = ['a', 'b', 'c'] print(type(my_list)) # 👉️ <class 'list'> print(isinstance(my_list, list)) # 👉️ True

The type class returns the type of an object.

The isinstance function returns True if the passed-in object is an instance or a subclass of the passed-in class.

# TypeError: slice indices must be integers or None or have an __index__ method

The Python "TypeError: slice indices must be integers or None or have an __index__ method" occurs when we use a non-integer value for slicing (e.g. a float).

To solve the error, make sure to use integers when slicing a list, string or any other sequence.

typeerror slice indices must be integers or none or have index method

Here is an example of how the error occurs.

main.py
my_list = ['a', 'b', 'c', 'd'] start = 0.5 stop = 2.5 # ⛔️ TypeError: slice indices must be integers or None or have an __index__ method result = my_list[start:stop]

We used floats for the start and stop values when slicing the list.

When slicing a sequence, we need to use integers for the start, stop and step values.

The syntax for list slicing is my_list[start:stop:step].

# Convert the values to integers when slicing

To solve the error, convert the floating-point values to integers.

main.py
my_list = ['a', 'b', 'c', 'd'] start = 0.5 stop = 2.5 result = my_list[int(start):int(stop)] print(result) # 👉️ ['a', 'b']

We passed the floating-point numbers to the int() class to convert them to integers.

Note that the value for start is inclusive whereas the value for stop is exclusive.
main.py
my_list = ['a', 'b', 'c', 'd'] print(my_list[0:2]) # 👉️ ['a', 'b'] print(my_list[1:3]) # 👉️ ['b', 'c']

If the start index is omitted, it is considered to be 0, if the stop index is omitted, the slice goes to the end of the list.

# The division operator always returns a floating-point number

The error often occurs when we use the division operator / because the division operator / always produces a float value

main.py
print(10/2) # 👉️ 5.0

Division / of integers yields a float, while floor division // of integers results in an integer.

main.py
print(10//2) # 👉️ 5
The result of using the floor division operator is that of a mathematical division with the floor() function applied to the result.

Once you use integers to slice the sequence, the error will be resolved.

# Checking what type the variable stores

If you aren't sure what type of object a variable stores, use the built-in type() class.

main.py
my_int = 10 print(type(my_int)) print(isinstance(my_int, int)) my_float = 3.14 print(type(my_float)) print(isinstance(my_float, float))

The type class returns the type of an object.

The isinstance() function returns True if the passed-in object is an instance or a subclass of the passed-in class.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.