How to Solve Python TypeError: ‘dict_values’ object is not subscriptable

by | Programming, Python, Tips

In Python, you cannot access values inside a dict_values object using indexing syntax.

A dict_keys object is a dynamic view object that displays all the keys in the dictionary.

You can solve this error by converting the dict_keys object to a list object using the built-in list() method. For example,

my_dict = {'particle':'electron', 'mass':0.511, 'charge': -1}
keys = list(my_dict.keys())
particle = keys[0]

This tutorial will detail the error and how to solve it with code examples.


TypeError: ‘dict_keys’ object is not subscriptable

Let’s break up the error message to understand what the error means. TypeError occurs whenever you attempt to use an illegal operation for a specific data type. The part “dict_values object” tells us the error concerns an illegal operation for the view object returned by the dictionary values() method.

The part “is not subscriptable” tells us we cannot access an element of the dict_keys object using the subscript operator, which is square brackets [].

A subscriptable object is a container for other objects and implements the __getitem__() method. Examples of subscriptable objects include strings, lists, tuples, and dictionaries.

We can check if an object implements the __getitem__() method by listing its attributes with the dir function. Let’s call the dir function and pass a dict_values object and a str object to see their attributes.

my_dict = {'fruit':'apple', 'in_stock':True, 'amount': 46}
vals = my_dict.values()
print(dir(vals))
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

We can see that __getitem__ is not present in the list of attributes for the dict_keys object.

string = "Python"
print(dir(string))
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

We can see that __getitem__ is present in the list of attributes for the str object.

If we want to check if a specific attribute belongs to an object, we can check for membership using the in operator. This approach is easier than looking through the list of attributes by eye.

my_dict = {'fruit':'apple', 'in_stock':True, 'amount': 46}
vals = my_dict.values()
# Check type of object
print(type(vals))
# Check membership of attribute
print('__getitem__' in dir(vals))
<class 'dict_values'>
False

We can see that __getitem__ is not an attribute of the dict_values class.

string = "Python"
print(type(string))
print('__getitem__' in dir(string))
<class 'str'>
True

We can see that __getitem__ is an attribute of the str class.

Example

Let’s look at an example of trying to index a dict_values object. First, we will create the dictionary.

my_dict = {"pizza_name":"margherita", "is_vegetarian":True, "price":7.99}

Then we will call the values() method on the dictionary, which returns a dictionary view object that displays all the values in the dictionary. The view object changes when the dictionary changes.

vals = my_dict.values()
print(type(vals))
<class 'dict_values'>

Next, we will try to access the first value in the dict_values object using the subscript operator [].

first_val = vals[0]
print(first_val)

Let’s run the code to see what happens:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [14], in <cell line: 1>()
----> 1 first_val = vals[0]
      2 print(first_val)

TypeError: 'dict_values' object is not subscriptable

The error occurs because we are trying to access the value using indexing, which is not possible with dict_values objects.

Solution

We can solve this error by converting the dict_values object to a list using the built-in list() method.

List objects are subscriptable in Python.

Let’s look at the revised code:

my_dict = {"pizza_name":"margherita", "is_vegetarian":True, "price":7.99}
vals = list(my_dict.values())
print(type(vals))
first_val = vals[0]
print(first_val)

Let’s run the code to get the first value:

<class 'list'>
margherita

Summary

Congratulations on reading to the end of this tutorial!

For further reading on AttributeErrors, go to the articles:

To learn more about Python for data science and machine learning, you can go to the online courses page on Python for the most comprehensive courses.

Have fun and happy researching!

Profile Picture
Senior Advisor, Data Science | [email protected] | + posts

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.

Buy Me a Coffee ✨