In Python, you cannot access values inside a generator
object using indexing syntax.
A generator function returns a generator object, an iterator containing a sequence of values. We can access the values in a generator object using a for loop or by calling next().
We can solve this error by converting the generator object to a list using the built-in list() method.
For example,
# A generator function def generator_func(): yield 1 yield 2 yield 3 # x is a generator object x = list(generator_func()) print(x[0])
This tutorial will go through how to solve the error with code examples.
TypeError: ‘generator’ 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 “generator object” tells us the error concerns an illegal operation for the generator
object.
The part “is not subscriptable” tells us we cannot access an element of the generator
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 generator
object and a str
object to see their attributes.
# A generator function def generator_func(): yield 1 yield 2 yield 3 x = generator_func() print(dir(x))
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
We can see that __getitem__
is not present in the list of attributes for the generator
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.
# A generator function def generator_func(): yield 1 yield 2 yield 3 x = generator_func() # Check type of object print(type(x)) # Check membership of attribute print('__getitem__' in dir(x))
<class 'generator'> False
The variable x
is an object of the generator class. We can see that __getitem__
is not an attribute of the generator 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 access an element of a generator
object using indexing. First, we will create the generator()
function.
Generator functions allow us to declare a function that behaves like an iterator. We use a yield
statement rather than a return
statement in a generator
function.
def generator_func(): yield 2 yield 3 yield 8
Next, we will assign the generator
object returned by the generator
function to a variable,
x = generator_func()
Next, we will attempt to access the first item in the generator
object using indexing syntax.
first_num = x[0] print(first_num)
Let’s run the code to see what happens:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Input In [41], in <cell line: 1>() ----> 1 first_num = x[0] 2 print(first_num) TypeError: 'generator' object is not subscriptable
The error occurs because the x
variable is a generator
object, which is an Iterator. Iterators generate values in order as requested by a for
loop or by calling next()
. We are trying to access values in the object as though it were a list
or another subscriptable object.
Solution
We can solve this error by converting the generator
object to a list
using the built-in list()
method.
Let’s look at the revised code:
def generator_func(): yield 2 yield 3 yield 8 x = list(generator_func()) first_num = x[0] print(first_num)
Let’s run the code to get the result:
2
The first item in the generator object is the number 2.
Summary
Congratulations on reading to the end of this tutorial!
For further reading on not subscriptable errors, go to the articles:
- How to Solve Python TypeError: ‘zip’ object is not subscriptable
- How to Solve Python TypeError: ‘dict_items’ object is not subscriptable
- How to Solve Python TypeError: ‘datetime.datetime’ object is not subscriptable
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!
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.