In Python, iterable objects are indexed by numbers. Attempting to access an iterable object with a string value will return an error. This error is similar to "TypeError: String indexes must be integers".
In this guide we are going to discuss what this error means and why it is generated. We’re going to walk through a sample snippet of code with this error and a workaround to give you more context on how to fix this type of error.
Let us begin!
The problem: typeerror: String indices must be whole numbersWe have a TypeError on our hands. This means that we are trying to perform an operation on a value whose type is incompatible with that operation. Let’s look at our error message:
typeerror: string indices must be integers
Like many Python error messages, this one tells us exactly what mistake we made. This error indicates that we are trying to access a value of an iterable using a string index instead of an integer index.
Iterables such as strings and dictionaries are indexed starting with the number 0. Consider the list below:
keyboard = ["Apex Pro", "Apple Magic Keyboard"];
This is a list of strings. To access the first item in this list, we need to refer to it by its index value:
print (keyboard [0])
This will return a keyboard name: "Apex Pro". We were unable to access this list item with a string. Otherwise an error would be returned.
An example scenario
Let’s create a dictionary called "steel_series" that contains information about a keyboard:
steel_series = { "name": "Apex Pro", "manufacturer": "SteelSeries", "oled_display": True }
We are going to loop through all of the values in this dictionary and print them out to the console.
for k in steel_series: print("Name: " + k["name"]) print("Manufacturer: " + k["manufacturer"]) print("OLED Display: " + str(k["oled_display"]))
This code uses a for loop to iterate over each element in our "keyboard" object. Now let’s try running our code and see what happens:
Traceback (most recent call last): File "main.py", line 8, inprint("Name: " + k["name"]) TypeError: string indices must be integers
There is a bug as we expected. This error occurs because we are trying to access the values in our dictionary by using string indexes instead of integers.
The solution
The problem with our code is that we iterate over every key in the steel_series dictionary.
The value of "k" is always a key in the dictionary. It is not an entry in our dictionary. Let’s try to print "k" in our dictionary:
for k in steel_series: print(k)
Our code returns:
name manufacturer oled_display
We cannot use "k" to access values in our dictionary. k ["name"] is equal to the value of "name" within "k", which is "name". This doesn’t make sense for Python. You cannot access a value in a string by using a different string.
To solve this problem, we need to refer to our dictionary instead of "k". We can access the elements of our dictionary via a string. This is because dictionary keys can be strings.
We don’t need to use a for loop to output each value:
print("Name: " + steel_series["name"]) print("Manufacturer: " + steel_series["manufacturer"]) print("OLED Display: " + str(steel_series["oled_display"]))
Let’s run our new code:
Name: Apex Pro Manufacturer: SteelSeries OLED Display: True
# string indices must be integers # Problem steel_series = { "name": "Apex Pro", "manufacturer": "SteelSeries", "oled_display": True } for k in steel_series: print("Name: " + k["name"]) print("Manufacturer: " + k["manufacturer"]) print("OLED Display: " + str(k["oled_display"])) # Solution print("Name: " + steel_series["name"]) print("Manufacturer: " + steel_series["manufacturer"]) print("OLED Display: " + str(steel_series["oled_display"]))
Our code successfully prints every value on our list. This is because we are no longer trying to access our dictionary using the string value in an iterator ("k").
Slice Notation string[x:y]
Python supports slice notation for any sequential data type like lists, strings , tuples, bytes, bytearrays, and ranges. When dealing with strings and slice notation, it can happen that a TypeError: string indices must be integers emerges, indicating out that the indices must be integers, even if they apparently are.
>>> str = "Hello World!" >>> str[0,4] Traceback (most recent call last): File "", line 1, in TypeError: string indices must be integers
A comma "," is actually enough for Python to evaluate something as a tuple. So here you need to replace the comma "," with a colon ":" to separate the two integers correctly.
>>> str = "Hello World!" >>> str[0:5] ’Hello’
Conclusion
String indices must be whole numbers. This means that when you access an iterable object, you must use a numeric value as a string. When accessing items in a dictionary, make sure that you are accessing the dictionary itself and not a dictionary key.
Now you’re ready to troubleshoot Python type errors: String indexes should be integer errors like a pro!