Last updated: Apr 8, 2024
Reading timeยท7 min
The Python "TypeError: 'dict_keys' object is not subscriptable" occurs when we try to access a dict_keys object at a specific index.
To solve the error, convert the dict_keys
object to a list, before accessing
an index, e.g. list(my_dict.keys())[0]
.
Here is an example of how the error occurs.
my_dict = {'name': 'Bobby Hadz', 'age': 30} keys = my_dict.keys() print(type(keys)) # ๐๏ธ <class 'dict_keys'> # โ๏ธ TypeError: 'dict_keys' object is not subscriptable print(keys[0])
Notice that the dict.keys()
method returns a dict_keys
object, not a list
.
dict_keys
object to a listTo solve the error, pass the dict_keys
object to the list
constructor to
convert it to a list before accessing a list item at a specific index.
my_dict = {'name': 'Bobby Hadz', 'age': 30} # โ Convert to a list keys = list(my_dict.keys()) print(keys[0]) # ๐๏ธ "name" print(keys[1]) # ๐๏ธ "age" print(keys[0:2]) # ๐๏ธ ['name', 'age']
The dict.keys() method returns a new view of the dictionary's keys.
dict_keys
objects are not subscriptable, we can't access them at a specific index.Once you convert the dict_keys
object to a list, you can also use list
slicing.
my_dict = {'name': 'Bobby Hadz', 'age': 30, 'country': 'Belgium'} keys = list(my_dict.keys()) print(keys[0:2]) # ๐๏ธ ['name', 'age'] print(keys[1:3]) # ๐๏ธ ['age', 'country']
The syntax for list slicing is
a_list[start:stop:step]
.
The start
index is inclusive and the stop
index is exclusive (up to, but not
including).
If the start
index is omitted, it is considered to be 0
, if the stop
index
is omitted, the slice goes to the end of the list.
Python indexes are zero-based, so the first item in a list has an index of 0
,
and the last item has an index of -1
or len(a_list) - 1
.
The solution is the same if you get one of the following errors:
You have to convert the dict_values
or dict_items
object to a list before
accessing it at an index.
Here is an example that does that for dict_values
.
my_dict = {'name': 'Bobby Hadz', 'age': 30} # โ convert to list values = list(my_dict.values()) print(values[0]) # ๐๏ธ "Bobby Hadz" print(values[1]) # ๐๏ธ 30 print(values[0:2]) # ๐๏ธ ['Bobby Hadz', 30]
And here is an example that does that for dict_items
.
my_dict = {'name': 'Bobby Hadz', 'age': 30} # โ Convert to a list items = list(my_dict.items()) print(items[0]) # ๐๏ธ ('name', 'Bobby Hadz') print(items[1]) # ๐๏ธ ('age', 30) print(items[0:2]) # ๐๏ธ [('name', 'Bobby Hadz'), ('age', 30)]
You can iterate over a dictionary's keys without having to convert the
dict_keys
object to a list.
my_dict = {'name': 'Bobby Hadz', 'age': 30, 'country': 'Belgium'} for key in my_dict.keys(): # name # age # country print(key)
On each iteration, we get access to the current key and print the result.
If you need to access the value of the current iteration, use the dict.items()
method instead.
my_dict = {'name': 'Bobby Hadz', 'age': 30, 'country': 'Belgium'} for key, value in my_dict.items(): # name Bobby Hadz # age 30 # country Belgium print(key, value)
try/except
Note that if you try to access a list index that is out of bounds, you would get an error.
You can use a try/except statement if you need to handle that.
my_dict = {'name': 'Bobby Hadz', 'age': 30} keys = list(my_dict.keys()) try: print(keys[100]) except IndexError: print('index out of bounds') # ๐๏ธ this runs
The example catches the IndexError
that is thrown if the index is out of
bounds.
Note that an IndexError
is not raised when you use list slicing, even if the
specified indices do not exist.
my_dict = {'name': 'Bobby Hadz', 'age': 30, 'country': 'Belgium'} keys = list(my_dict.keys()) print(keys[100:200]) # ๐๏ธ [] print(keys[1:100]) # ๐๏ธ ['age', 'country']
The list constructor
takes an iterable, such as a dict_keys
object, and converts it to a list.
list
constructor builds a list whose items are the same and in the same order as the iterable's items.The list
constructor takes an iterable that may be a sequence, a container
that supports iteration or an iterator object.
You should only use square brackets to access subscriptable objects.
The subscriptable objects in Python are:
All other objects have to be converted to a subscriptable object by using the
list()
, tuple(), dict()
or
str() classes to be able to use bracket
notation.
Subscriptable objects implement the __getitem__
method whereas
non-subscriptable objects do not.
a_list = [2, 4, 6, 8] # ๐๏ธ <built-in method __getitem__ of list object at 0x7f71f3252640> print(a_list.__getitem__)
The Python "TypeError: 'generator' object is not subscriptable" occurs when we try to access a generator object at a specific index.
To solve the error, pass the generator to the list constructor, e.g.
list(gen)[0]
.
Here is an example of how the error occurs
def g(): yield 1 yield 2 yield 3 gen = g() print(type(gen)) # โ๏ธ TypeError: 'generator' object is not subscriptable print(gen[0])
We used square brackets to try to access the element at index 0
, but the
generator
object is not subscriptable.
We can get around this by converting the generator
object to a list.
def g(): yield 1 yield 2 yield 3 # โ convert generator object to list my_list = list(g()) print(my_list) # ๐๏ธ [1, 2, 3] print(my_list[0]) # ๐๏ธ 1 print(my_list[1]) # ๐๏ธ 2
List objects are subscriptable, so we can access the element at a specific index
after converting the generator
object to a list.
You can iterate over a generator with a simple for loop.
def g(): yield 1 yield 2 yield 3 gen = g() for i in gen: print(i) # ๐๏ธ 1, 2, 3
Alternatively, you can pass the generator
to the next()
function to retrieve
the next item.
def g(): yield 1 yield 2 yield 3 gen = g() print(next(gen)) # ๐๏ธ 1 print(next(gen)) # ๐๏ธ 2 print(next(gen)) # ๐๏ธ 3
Note that if you try to access a list index that is out of bounds, you will get
an error. You can use a try/except
statement if you need to handle that.
def g(): yield 1 yield 2 yield 3 my_list = list(g()) try: print(my_list[100]) except IndexError: print('index out of bounds') # ๐๏ธ this runs
The example catches the IndexError
that is thrown if the index is out of
bounds.
The list constructor
takes an iterable, such as a generator
object, and converts it to a list.
list
constructor builds a list whose items are the same and in the same order as the iterable's items.The list
constructor takes an iterable that may be a sequence, a container
that supports iteration or an iterator object.
You should only use square brackets to access subscriptable objects.
The subscriptable objects in Python are:
All other objects have to be converted to a subscriptable object by using the
list()
, tuple()
, dict()
or str()
classes to be able to use bracket
notation.
Subscriptable objects implement the __getitem__
method whereas
non-subscriptable objects do not.
a_list = ['bobby', 'hadz', 'com'] # ๐๏ธ <built-in method __getitem__ of list object at 0x7f71f3252640> print(a_list.__getitem__)
The Python "TypeError: 'map' object is not subscriptable" occurs when we try
to access a map
object at a specific index.
To solve the error, convert the map
object to a list before accessing it at
an index, e.g. new_list = list(map(int, a_list))
.
Here is an example of how the error occurs.
a_list = ['2', '4', '6', '8'] new_list = map(int, a_list) print(new_list) # ๐๏ธ <map object at 0x7fde832679a0> # โ๏ธ TypeError: 'map' object is not subscriptable print(new_list[0])
In Python 3, the map()
function returns a map
object, not a list.
list()
class to convert the map
object to a list.a_list = ['2', '4', '6', '8'] new_list = list(map(int, a_list)) print(new_list) # ๐๏ธ [2, 4, 6, 8] print(new_list[0]) # ๐๏ธ 2
The map() function takes a function and an iterable as arguments and calls the function with each item of the iterable.
The function returns a map
object and map
objects are not subscriptable
(cannot be accessed at an index).
You can use square brackets if you need to access:
for
loop to iterate over the map
object without having to convert it to a list.a_list = ['2', '4', '6', '8'] new_list = [] map_obj = map(int, a_list) for item in map_obj: print(int(item)) new_list.append(int(item)) print(new_list) # ๐๏ธ [2, 4, 6, 8] print(new_list[0]) # ๐๏ธ 2 print(new_list[:2]) # ๐๏ธ [2, 4]
Map objects are evaluated lazily, so we used a for
loop to iterate over the
object.
You can optionally append the result of calling a function with each item to a list.
A better approach than having to convert a map object to a list is to use a list comprehension.
a_list = ['2', '4', '6', '8'] new_list = [int(item) for item in a_list] print(new_list) # ๐๏ธ [2, 4, 6, 8]
We used a list comprehension to iterate over the original list.
On each iteration, we call the int() class with the current item and return the result.
The list comprehension returns a new list containing the results.
map
function. All you have to do is call a function with each list item and return the result.You can also use a list comprehension or the map
function with user-defined
functions.
def do_math(a): return a + 100 a_list = [2, 4, 6, 8] result = list(map(do_math, a_list)) print(result) # ๐๏ธ [102, 104, 106, 108] print(result[0]) # ๐๏ธ 102 result = [do_math(item) for item in a_list] print(result) # ๐๏ธ [102, 104, 106, 108] print(result[0]) # ๐๏ธ 102
The error basically means that the object cannot be accessed using square brackets.
You should only use square brackets to access subscriptable objects.
The subscriptable objects in Python are:
All other objects have to be converted to a subscriptable object by using the
list()
, tuple()
, dict()
or str()
classes to be able to use bracket
notation.
Subscriptable objects implement the __getitem__
method whereas
non-subscriptable objects do not.
a_list = [1, 2, 3] # ๐๏ธ <built-in method __getitem__ of list object at 0x7f71f3252640> print(a_list.__getitem__)
You can learn more about the related topics by checking out the following tutorials: