The “TypeError: list indices must be integers or slices, not str” error is raised when we try to access a value of a list using anything but numbers or slices. This error is usually solved by calling the int() function on our string, but it depends on the context.
Remember that lists is a data-type used to store items, where items are indexed, the first item being assigned the 0 index, the second the 1 index … If you want to access the last element of a list, you have to use negative indexing, -1 representing the last one and -2 the element before that.
my_list = [1,2,3,4,5]
first_element = my_list[0] #1
last_element = mylist[-1] #5
Code language: Python (python)
You can also use slices when you are looking to obtain a part of your initial list. For instance, this code will allow you to get the first two items:
my_list = [1,2,3,4,5]
first_two_elements = my_list[0:2] #[1,2]
Code language: Python (python)
Now, if you decide to use anything but these two structures, Python will throw an error. Let’s see what the most common situations are and how to fix them.
Table of Contents
Unconverted strings
Let’s assume in this example that you are an E-commerce selling three products, a book, sold at $10, a video game, sold at $50, and a gaming console, sold at $200. The user can pick the products and the quantity, and you’ll return the price.
The code behind your E-commerce would look like this:
#list of prices
prices = [20,50,200]
#ask user what product he/she wants to buy
product = input('What product do you want? 1: Book, 2: Video Game, 3: Gaming Console')
#ask quantity
quantity = input('How many products do you want to purchase')
#calculate price
price = prices[product] * quantity
Code language: Python (python)
If you run this code, you’ll run into our error:
TypeError: list indices must be integers or slices, not str
Code language: Python (python)
By default, the result of an input() is store as a string (even if it represents a number) and we need to convert it to a numerical value using the int class.
#list of prices
prices = [20,50,200]
#ask user what product he/she wants to buy
product = int(input('What product do you want? 1: Book, 2: Video Game, 3: Gaming Console'))
#ask quantity
quantity = input('How many products do you want to purchase')
#calculate price
price = prices[product] * quantity
Code language: Python (python)
Note that Python is very precise when it comes to errors: it throws a TypeError because the data type we are using is not the correct one.
Confusion between lists and dictionaries
Let’s assume we want to print the different values stores in one list. We could run the following code:
cities = ['Paris', 'New York', 'Barcelona', 'Berlin']
for city in cities:
print(cities[city])
Code language: Python (python)
But again, Python will raise our error:
TypeError: list indices must be integers or slices, not str
Code language: JavaScript (javascript)
This is because we got confused between lists and dictionaries when it comes to how we can access their values. Indeed, the loop we execute before would work with the following code:
cities = ['Paris', 'New York', 'Barcelona', 'Berlin']
for i in range(0, len(cities)):
print(cities[i])
Code language: Python (python)
When it comes to lists, we need an index (numerical) value to access a value, and we can use the range function to achieve that.
List of dictionaries
Finally, there is one situation I’ve personally encountered countless times. If you work with API, data is often returned in a JSON format, we can convert to a Python object using json.loads(). Even if you expect one result, data is often stored inside a list, as shown below:
api_result = [{'date':'2022-10-01', 'invoices':100}]
Code language: JavaScript (javascript)
You can quickly forget about the square brackets and think you are dealing with a simple dictionary. You’ll then try to execute the following code, which will raise the same error:
api_result = [{'date':'2022-10-01', 'invoices':100}]
date = api_result['date']
Code language: Python (python)
One quick way to avoid this mistake is to use the isinstance() function to double-check the object type you are dealing with and adapt your code accordingly:
api_result = [{'date':'2022-10-01', 'invoices':100}]
if isinstance(api_result, list):
date = api_result[0]['date']
elif isinstance(api_result, dict):
date = api_result['date']
Code language: Python (python)