TypeError Object Is Not Subscriptable in Python

Python throws TypeError <object> is not subscriptable if you attempt to access a value in an object which is not indexable using the indexer operator ([ ]).

An indexable/ subscriptable object contains the __getitem__() magic/dunder function, which allows the object to act as a container of some elements.

In python, indexable objects include lists, tuples, strings, and arrays, whereas sets, None, numeric values (integers and floats), and dictionary values are not.

Output:

John
John

As shown in the output, the indexer operator ([ ]) calls the dunder function __getitem__() in the background, which is why both ways of indexing yield the same result.

Reproducing TypeError: Object Is Not Subscriptable

This error arises when we try to index an object which is not subscriptable. Here are some examples.

Output:

TypeError: 'int' object is not subscriptable

Output:

{345, 'Simon', -7, 1}
TypeError: 'set' object is not subscriptable

So far, we have seen that integers and sets are not subscriptable; therefore, trying to index them leads to an error.

Integers are not container objects and, therefore, not indexable. On the other, Python set is an unordered collection of unique elements. The unordered nature of Python sets makes them inherently non-subscriptable.

You can use the dir() function to check attributes supported by a given object. For example, dir(num1) and dir(set1) will show you that they don’t support the magic function __getitem__().

Output:

dict_values(['Smith', 'Biology', 2])
TypeError: 'dict_values' object is not subscriptable

The operator, [ ], in the Python dictionary is used to access dictionary values using corresponding keys. For example, dict1[“name”] will yield “Smith” in the code above.

Just like integers and sets, dictionary values are not indexable. The dict_values object is a set-like object and uses a hash table to store its items, which is unsuitable for indexing.

This explanation holds in Python3 only. Dictionary values are indexable in Python 2; therefore, the code above will not yield an error in Python 2.

The Solution to TypeError: Object Is Not Subscriptable

Depending on the nature of this error, there are three solutions. Let’s discuss them as we give examples.

The first solution to this error is to ensure you are not indexing a non-subscriptable object. Secondly, you can cast non-indexable Python objects into indexable forms.

For example, in the case of dict_values, we can convert it into a list and index it accordingly. The same applies to Python sets – they can be converted to a list and then accessed items by index.

Output:

dict_values(['Smith', 'Biology', 2])
Smith

Output:

[345, -7, 1, 'Simon']
345

Note: Be careful when indexing sets converted into a list because they may not yield the expected results. Python sets are unordered. They do not preserve the order when cast into another data type ( even when printed).

Another solution is to create the __getitem__() magic function on the object you want to make it subscriptable, if possible. For example, consider the following Persons() class.

Output:

TypeError: 'Persons' object is not subscriptable

Python class object is not indexable, and therefore we get the error. We can modify the class by adding the __getitem__() function, and the object will be indexable.

Output:

Bob

The use of __getitem__() in the class allowed us to use the indexer operator ([ ]) with the reference variables of the Persons class to access values of the “names” list.

When we try to access an element in p1 using p1[1], the p1.__getitem__() is automatically called. The dunder function takes the index as an argument and returns the name associated with the given index.

Conclusion

Python throws TypeError <object> is not subscriptable when we try to index an object which is not indexable.

In this article, we showed how and why this error occurs and covered three ways of solving this problem: avoid indexing non-subscriptable objects, cast non-indexable objects into indexable form, and lastly, create __getitem__() function and use it accordingly to enable indexing of otherwise non-subscriptable.