Python Dictionary Not Subscriptable

Python throws the TypeError <object> is not subscriptable if you attempt to index using index operator ([ ]), an object which is not indexable. An indexable object contains the  __getitem__() magic/dunder function, which allows the object to act as a container for some items.

In Python, indexable objects include lists, strings, arrays, and tuples, whereas sets, None, numeric, and dictionary values are not.

When you index a list, for example, say lst1[i], Python internally calls the dunder method __getitem__() as lst1.__getitem__(i), just like when we run x+y Python executes this as x.__add__(y).

a, b = 3, 4
c = a.__add__(b)
print(c)
lst1 = ["Smith", 44, None]
print(lst1[0])
print(lst1.__getitem__(0))

Output:

7
Smith
Smith

Note: In some cases, the object class being indexed may not have the __geitem__() magic method explicitly defined but instead inherits the property from an ancestor or parent class.

Reproducing <object> is not Subscriptable Error

If you index an object which is not a container, you will end up with this error. For example,

num1 =  19.7
num1[0]

Output:

TypeError: 'set' object is not subscriptable

Sets are an unordered collection of unique elements. This makes it not subscriptable.

Running in Python 3:

dictionary1 = {
	'name': "Bob",
	'dict1': {'adm': 44},
}

print(dictionary1.values())
print(dictionary1.values()[0])

Output:

TypeError: 'dict_values' object is not subscriptable

In Python, dictionary values are accessed using the keys. For example, dictionary1[“name”] yields “Bob”.

When we extract dictionary values into the dict_values object and try to index this object, we end in an error. 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 applies only to Python 3.

In Python 2, dict_values are indexable.

Running in Python 2:

dictionary = {
	'name': "Decker",
	'dict1': {'adm': 44},
}
print(dictionary.values()[0])

Output:

{'adm': 44}

The Solution to the Error

Whenever you end up with this TypeError, inspect the objects you are indexing and fix the problem by avoiding the index or casting it into another indexable object.

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

dictionary1 = {
	'name': "Bob",
	'dict1': {'adm': 44},
}
print(dictionary1.values())
# cast it into list then we can access values by indexing
value = list(dictionary1.values())[0]
print(value)

Output:

dict_values(['Bob', {'adm': 44}])
Bob

Alternatively, you can create the __getitem__() method on an object you wish to make indexable. For instance, in the example below:

class MyObject():
def __getitem__(self, index):
return index ** 2
print(MyObject()[2])
print(MyObject()[5])

Output:

4
25

As you can see, MyObject() class can be indexed with the index operator. We are using the __getitem_() to compute squares (misusing it, kind of).

Conclusion

At the end of the article, I hope you now clearly understand the TyperError <object> is not subscriptable. You should be able to identify the cause of the error and then get a solution.