Can one call another person by typing their name in the dial pad? NO! Typing password in the password field to log in? ( although it might work sometimes ). Or take revenge on a useless person by using one’s own precious time and energy? All of the mentioned takes on problems are futile and a little bit imbecilic. But still, we do it. Nothing to worry about in each task requires slight patience and common sense. The problem that we will discuss in the article is likewise. We will discuss Python Type Error here.
SYNOPSIS:
First of all, let us understand what an iterable object: An iterable is an object, which returns one of its members at a time, allowing it to be iterated over in for-loop is. In Python, iterable objects are indexed or placed in the data structures such as string or dictionary using numbers, i.e., integer. When values at index are extracted using string value (incorrect type of input), it raises error like this :
Python Type Error: string indices must be integers
The following article will interpret whether when and how the error occurs and how to resolve the error by understanding certain data structures’ anatomy via different scenarios. Each problem instance will be understood in-depth, the meaning will be interpreted, and eventually solved.
THE PROBLEM:
When one starts coding or is a beginner, it is the most annoying thing to go through as a programmer. It seems like the world has come to an end, and one might never master the art of coding. One is almost on the verge of giving up, but one should not forget the world’s best programmers were naïve in the beginning. They started somewhere and went through all of the errors and technical issues to be at the top of their game. So are you. One must not give up that fast. Let us clear some air and gear up!
To begin with, one must know the anatomy of the problem to solve it. Here the problem we have is surely arising because of the incompatibility of the argument we pass through our data structure. Let us understand how and when an error can arise through a couple of illustrations.
Scenario 1:
Suppose we have a string as shown below. Since Python is a dynamically typed language, i.e., the type of variable is checked during the run-time, we need not mention keywords like int, str, or char before the variable is used. We try to index a part of the string, which is a way to refer to an individual item within an iterable (string) by its position. In Python, objects are zero-indexed, i.e., the position count starts at zero. Now we want to access the letter ‘e’ from the string, one may follow the given approach:
In [1]: string=”typeerror”In [2]: string[‘e’]Traceback (most recent call last): File “<ipython-input-8-1b9006e9beb0>”, line 1, in <module>string[‘e’] TypeError: string indices must be integers |
The error is self-explanatory but let us read what the message is trying to say. Python is an interpreted language that will stop compiling the program as soon as syntax errors exist and will not run unless the problem is solved. It might confuse us that the error is at the second line, but it says line 1. In the environment, I have used Spyder part of a Python distribution, Anaconda. The first line is called line 0. Thus, line 1 displays a type error which denotes that the value of the indices provided is of another type. We are trying to extract a value from a string using a string index instead of an integer index. Look at the following infographic to understand what exactly a string looks like and how the items are indexed in the iterable:
t | y | p | e | e | r | r | o | r |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Scenario 2:
Another way to extract a part of text from a string is via slicing. Slicing is a technique of getting a subset of elements (i.e., a small list based on index value) of the iterable (list). It has prominent applications in optimization, error analysis, debugging, flow control, and many more. Let us walk through an example:
In [3]: mystring=”gratitude” In [4]: mystring[0,5]Traceback (most recent call last): File “<ipython-input-13-7c2881597196>”, line 1, in <module>mystring[0,5] TypeError: string indices must be integers |
How come? Although we have used integer indexes to slice the iterable, it shows the same error of compatibility issue and, to be honest, not a correct explanation to the mistake we have made. We need to dig a litter deeper. Thus we will save the integer index in another string object and then look up the same.
In [5]: extract=0,5 In [6]: type(extract)Out[6]: tuple |
Because it is a tuple that one of the built-in data types in Python other than List, Set, and Dictionary, it did not show the expected output. The comma in the string is automatically evaluated as a tuple and makes the error misleading. Therefore, the error should have been something like this:
In [7]: mystring[extract]Traceback (most recent call last): File “<ipython-input-16-308e1ed6160d>”, line 1, in <module>mystring[extract] TypeError: string indices must be integers(not tuple) |
To learn more about data types of Python visit the following link: Python data types
Scenario 3:
Next data structure is a dictionary, and it is slightly complex than a list thus, we must know how the structure is:
Dictionary={
key1 : value1,
key2 : value2,
.
.
keyN : valueN,
}
The key could be any entity like name, address, gender, and phone, while values are the attributes like Max for a name. One key can even have multiple values separated by commas and double or single-quoted.
Let us create a dictionary called “phone_book” with the keys ‘Name’, ‘Mobile’, and ‘Address’ however, we will take a simpler dictionary for better understanding.
In [8]: phone_book={ “Name”: “Jennifer Aniston”,”Phone”: “1800”, “Address”: “Apt20” } |
In order to iterate over all the values in the dictionary and print them all, we will use the following code snippet, where k is for all the keys residing in the dictionary:
In [9]: for k in phone_book: …: print(“Name:” + k[“Name”]) …: print(“Phone:” + k[“Phone”]) …: print(“Address:” + k[“Address”])Traceback (most recent call last): File “<ipython-input-20-e5c1b8f425c3>”, line 2, in <module>print(“Name:” + k[“Name”]) TypeError: string indices must be integers |
Sigh! The error is present because we are trying to access values using string index instead of the integer index. However, that is not all that it is shown and will elucidate further in the solutions section.
THE SOLUTION:
Scenario 1:
Since we were using string index, we got the type error because values are stored at an address starting from 0 in both string and dictionary. Now we will try to index the string using the integer as that is the correct way to extract information.
In [10]: string[0]Out[10]: ‘t’ |
Voila! It displayed what we were looking for. Try yourself to extract items at different locations of iterable by passing values from 0-8. Wondering why and how 8? As we saw in the above infographic, it had nine letters, and the numbering started from zero. The last one is eight. But what if the string is longer and we have not much time to count each letter and space(yes, space counts), one can do the following to get the size of the string:
In [11]: string1 = “Hi there”In [12]: len(string1)Out[12]: 7 |
Scenario 2:
Since we were slicing the string using a comma, we got the type error as Python evaluates commas, as tuple thus we replace that with a colon ‘:’. Follow the code below:
In [13]: mystring[0:5]Out[13]: ‘grati’ |
Scenario 3:
In dictionary we tried to access the values using ‘k’ and passing the keys to it, but the problem is that in the for a loop as explained clearly below:
- k is a key,
- key is ‘Name’ in the dictionary ‘phone_book’ and
- we pass ‘Name’ to ‘Name’ to get the value.
We cannot use string to access other string. Perplexed right? It is like opening a lock using a lock. The following code will make it clearer.
In [14]: for k in phone_book: …: print(k) …: NamePhoneAddress |
Here, we tried to access the key’s value( dict[key: value] ) bypassing the key name itself, but the method to do it is bypassing the index or position of the item in an object like string, and for the dictionary, the name of the dictionary is to be mentioned to retrieve them. Thus, the solution to this is that we must use the dictionary name instead of ‘k’ as the dictionary key can be strings. Thus, follow the below method:
In [15]: phone_book={ …: “Name”: “Jennifer Aniston”, …: “Phone”: “1800”, …: “Address”: “Apt20”, …: } In [16]: print(“Name:” + phone_book[“Name”]) …: print(“Phone:” + phone_book[“Phone”]) …: print(“Address:” + phone_book[“Address”]) Name: Jennifer AnistonPhone:1800Address: Apt20 |
Our code ran successfully! Since we diagnosed the cause of the problem, it became clearer and easier to solve it. The wrong argument passed to search the available content in the iterable ( strings, dictionaries) raised the error. Following that, we made changes accordingly and, therefore, could get the expected output, i.e., the item/alphabet at the mentioned location of string and details of dictionary with key and its value.
CONCLUSION:
The lesson learned is that:
- string indices must be an integer ( string[0] ) and
- slicing is done through colon ‘:’ ( string[0:1] ) not commas ‘,’ as Python thinks it a tuple.
- Moreover, dictionary items must be accessed only using a dictionary name, NOT a key in the dictionary. There you go! Now you can solve this error and work like a pro!
Apart from this some best practices to excel in programming are as follows:
- Code daily! Yes, one has to make it a habit to excel in the realm.
- Please participate in hackathons on websites like Kaggle, CodeChef, Google, and many others to know one’s strengths and improve the weaknesses.
- Network or connect with people on Linkedin to follow in their footsteps and take advice from them when you hit the pit.
- There are always these Job-a-thons going on, like hackathons, but if one excels in that, one can make a career out of it.
- Spend a considerable amount of time reading books available online and famous blog posts on Medium or any openly available one.
- Great websites like Coursera, Udemy, edX, Udacity, and many more to start fresh and finish a pro!
- Lastly, ask for help, whether in-person, online or Google it away on platforms like StackOverflow and GitHub, by submitting the code and ask one’s query.
Therefore, the way one approaches an issue has a big role in resolving it within a less time frame. On top of that, a little knowledge about the workings of the language makes it much easier to understand the error. Like in this case, it was TypeError: string indices must be integers. If one does not know what an index is, it makes it a head-scratcher. While knowing it in the first place would have made it possible to solve it independently.
To learn more about errors and exception in Python visit the link: Errors and Exceptions
As a beginner, one must start in environments like Spyder which has a considerable number of modules pre-installed in it.
The link leads to install Anaconda distribution(choose as per your OS): Anaconda Installation
Follow the documentation to install the Anaconda successfully: Installation Guide
Keep visiting the sites of your installed environment because:
- They have a detailed explanation of the errors and all the elements in a language.
- Updated versions must be installed as they include bug fixes and new improvements.
- They even include a plethora of tutorials for new learners.
- New products from the distributor can be helpful in many ways.
Also read Papa John’s Careers: Job Application, Salary & Benefits