TypeError: list indices must be integers or slices, not str
Why does this occur?
This error occurs when using a string for list indexing instead of indices or slices. For a better understanding of list indexing, see the image below, which shows an example list labeled with the index values:
Using indices refers to the use of an integer to return a specific list value. For an example, see the following code, which returns the item in the list with an index of 4:
Using slices means defining a combination of integers that pinpoint the start-point, end-point and step size, returning a sub-list of the original list. See below for a quick demonstration of using slices for indexing. The first example uses a start-point and end-point, the second one introduces a step-size (note that if no step-size is defined, 1 is the default value):
As a budding Pythoneer, one of the most valuable tools in your belt will be list indexing. Whether using indices to return a specific list value or using slices to return a range of values, you'll find that having solid skills in this area will be a boon for any of your current or future projects.
Today we'll be looking at some of the issues you may encounter when using list indexing. Specifically, we'll focus on the error
TypeError: list indices must be integers or slices, not str, with some practical examples of where this error could occur and how to solve it.
Cause 1: Unconverted Strings
For a quick example of how this could occur, consider the situation you wanted to list your top three video games franchises. In this example, let's go with Call of Duty, Final Fantasy and Mass Effect. We can then add an input to the script, allowing the user to pick a list index and then print the corresponding value. See the following code for an example of how we can do this:
We're getting the
TypeError in this case because Python is detecting a string type for the list index, with this being the default data type returned by the
input() function. As the error states, list indices must be integers or slices, so we need to convert our choice variable to an integer type for our script to work. We can do this by using the
int() function as shown below:
Our updated program is running successfully now that 1 is converted from a string to an integer before using the choice variable to index the list, giving the above output.
Cause 2: Treating Lists as Dictionaries
Building on the previous example, let's create a list of JSON objects. In this list, each object will store one of the game franchises used previously, along with the total number of games the franchise has sold (in millions). We can then write a script to output a line displaying how many games the Call of Duty franchise has sold.
This error occurs because we have accidentally tried to access the dictionary using the
"Name" key, when the dictionary is inside of a list. To do this correctly, we need first to index the list using an integer or slice to return individual JSON objects. After doing this, we can use the
"Name" key to get the name value from that specific dictionary. See below for the solution:
Our new script works because it uses the integer type
i to index the list and return one of the franchise dictionaries stored in the list. Once we've got a dictionary type, we can then use the
"Units Sold" keys to get their values for that franchise.
Cause 3: Using List Values for Indexing
A slightly different cause we can also take a look at is the scenario where we have a list of items we'd like to iterate through to see if a specific value is present. For this example, let's say we have a list of fruit and we'd like to see if orange is in the list. We can easily make the mistake of indexing a list using the list values instead of integers or slices.
In this case, we're getting the error because we've used the string values inside the list to index the list. For this example, the solution is pretty simple as we already have the list values stored inside the fruit variable, so there's no need to index the list.
As you can see, there was no need for us to index the list in this case; the list values are temporarily stored inside of the fruit variable as the
for statement iterates through the list. Because we already have the fruit variable to hand, there's no need to index the list to return it.
For future reference, an easier way of checking if a list contains an item is using an
if in statement, like so:
Or if you want the index of an item in the list, use
Bear in mind that using
.index() will throw an error if the item doesn't exist in the list.
This type error occurs when indexing a list with anything other than integers or slices, as the error mentions. Usually, the most straightforward method for solving this problem is to convert any relevant values to integer type using the
int() function. Something else to watch out for is accidentally using list values to index a list, which also gives us the type error.