List indexing is a valuable tool for you as a Python developer. You can extract specific values or ranges of values using indices or slices. You may encounter the TypeError telling you that the index of the list must be integers or slices but not strings. In this part of Python Solutions, we will discuss what causes this error and solve it with several example scenarios.
Table of contents
Why Does This Error Occur?
Each element in a list object in Python has a distinct position called an index. The indices of a list are always integers. If you declare a variable and use it as an index value of a list element, it does not have an integer value but a string value, resulting in the raising of the TypeError.
In general, TypeError in Python occurs when you try to perform an illegal operation for a specific data type.
You may also encounter the similar error “TypeError: list indices must be integers, not tuple“, which occurs when you try to index or slice a list using a tuple value.
Let’s look at an example of a list of particle names and use indices to return a specific particle name:
particle_list = ['gluon', 'photon', 'muon', 'electron', 'Z-boson']
value = particle_list[2]
print(value)
muon
You can also use slices, which define an integer combination: start-point, end-point, and step-size, which will return a sub-list of the original list. See the slice operation performed on the particle list:
sub_list_1 = particle_list[3:5]
print(sub_list_1)
['electron', 'Z-boson']
sub_list_2 = particle_list[1:5:2]
print(sub_list_2)
['photon', 'electron']
In the second example, the third integer is the step size. If you do not specify the step size, it will be set to the default value of 1.
Iterating Over a List
When trying to iterate through the items of a list, it is easy to make the mistake of indexing a list using the list values, strings instead of integers or slices. If you try iterating over the list of particles using the particle names as indices, you will raise the TypeError
particle_list = ['gluon', 'photon', 'muon', 'electron', 'Z-boson']
for particle in particle_list:
if particle_list[particle] == 'electron':
print('Electron is in the list!')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
1 for particle in particle_list:
2 if particle_list[particle] == 'electron':
3 print('Electron is in the list!')
4
TypeError: list indices must be integers or slices, not str
Here, the error is raised because we are using string values as indices for the list. In this case, we do not need to index the list as the list values exist in the particle variable within the for statement.
Solution
particle_list = ['gluon', 'photon', 'muon', 'electron', 'Z-boson']
for particle in particle_list:
if particle == 'electron':
print('Electron is in the list!')
Electron is in the list!
We can use the if in statement to check if an item exists in a list as discussed in the Python: Check if String Contains a Substring. For example:
particle_list = ['gluon', 'photon', 'muon', 'electron', 'Z-boson']
if 'electron' in particle_list:
print('Electron is in the list!')
Electron is in the list!
Incorrect Use of List as a Dictionary
We can treat the list of particle names to include their masses and store the values as a list of JSON objects. Each object will hold the particle name and mass. We can access the particle mass using indexing. In this example, we take the electron, muon and Z-boson:
particles_masses = [
{
"Name": "electron",
"Mass": 0.511
},
{
"Name": "muon",
"Mass": 105.7
},
{
"Name": "Z-boson",
"Mass": 912000
}
]
if particles_masses["Name"] == 'muon':
print(f'Mass of Muon is: {particles_masses["Mass"]} MeV')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
1 if particles_masses["Name"] == 'muon':
2 print(f'Mass of Muon is: {particles_masses["Mass"]} MeV')
3
TypeError: list indices must be integers or slices, not str
We see the error arise because we are trying to access the dictionary using the “Name” key, but the dictionary is actually inside a list. You must first access the dictionary using its index within the list.
Solution 1: Using range() + len()
When accessing elements in a list, we need to use an integer or a slice. Once we index the list, we can use the “Name” key to get the specific element we want from the dictionary.
for i in range(len(particles_masses)):
if particles_masses[i]["Name"] == 'muon':
print(f'Mass of Muon is: {particles_masses["Mass"]} MeV')
Mass of Muon is: 105.7 MeV
The change made uses integer type I to index the list of particles and retrieve the particle dictionary. With access to the dictionary type, we can then use the “Name” and “Mass” keys to get the values for the particles present.
Solution 2: Using enumerate()
You can access the index of a dictionary within the list using Python’s built-in enumerate method as shown below:
for n, name in enumerate(particles_masses):
if particles_masses[n]["Name"] == 'muon':
print(f'Mass of Muon is: {particles_masses[n]["Mass"]} MeV')
Mass of Muon is: 105.7 MeV
Solution 3: Using Python One-Liner
A more complicated solution for accessing a dictionary is to use the search() function and list-comprehension
search = input("Enter particle name you want to explore: ")
print(next((item for item in particles_masses if search.lower() in item ["Name"].lower()), 'Particle not found!'))
Enter particle name you want to explore: muon
{'Name': 'muon', 'Mass': 105.7}
Not Converting Strings
You may want to design a script that takes the input to select an element from a list. The TypeError can arise if we are trying to access the list with a “string” input. See the example below:
particles_to_choose = ["electron", "muon", "Z-boson"]
chosen = input('What particle do you want to study? (0, 1, or 2)?')
print(particles_to_choose[chosen])
What particle do you want to study? (0, 1, or 2)?1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
1 print(particles_to_choose[chosen])
TypeError: list indices must be integers or slices, not str
The error arises because the index returned by the input() function’s default, which is “string”. To solve this, we need to convert the input chosen to an integer type. We can do this by using the int() function:
particles_to_choose = ["electron", "muon", "Z-boson"]
chosen = int(input('What particle do you want to study? (0, 1, or 2)?'))
print(particles_to_choose[chosen])
What particle do you want to study? (0, 1, or 2)?1
muon
Summary
This TypeError occurs when you try to index a list using anything other than integer values or slices. You can convert your values to integer type using the int() function. You can use the “if… in” statement to extract values from a list of strings. If you are trying to iterate over a dictionary within a list, you have to index the list using either range() + len(), enumerate() or next().
If you are encountering other TypeError issues in your code, I provide a solution for another common TypeError in the article titled: “Python TypeError: can only concatenate str (not “int”) to str Solution“.
Thanks for reading to the end of this article. Stay tuned for more of the Python Solutions series, covering common problems data scientists and developers encounter coding in Python. If you want to explore educational resources for Python in data science and machine learning, go to the Online Courses Python page for the best online courses and resources. Have fun and happy researching!
Suf is a senior advisor in data science with deep expertise in Natural Language Processing, Complex Networks, and Anomaly Detection. Formerly a postdoctoral research fellow, he applied advanced physics techniques to tackle real-world, data-heavy industry challenges. Before that, he was a particle physicist at the ATLAS Experiment of the Large Hadron Collider. Now, he’s focused on bringing more fun and curiosity to the world of science and research online.