How to Solve Python TypeError: ‘_csv.reader’ object is not subscriptable

by | Programming, Python, Tips

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

The reader() method from the csv module returns a _csv.reader object, which is an iterable containing the lines of the file.

We can solve this error by converting the _csv.reader object to a list using the built-in list method.

For example,

import csv

with open('pizzas.csv', newline='') as f:

   reader = list(csv.reader(f))

   print(reader[1])

We can also iterate over the lines in the _csv.reader object using a for loop.

This tutorial will go through the error in detail with code examples.


TypeError: ‘_csv.reader’ 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 “_csv.reader object” tells us the error concerns an illegal operation for the _csv.reader object.

The part “is not subscriptable” tells us we cannot access an element of the _csv.reader 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 _csv.reader object and a str object to see their attributes. We will read in a file called pizzas.csv containing the following data:

pizza,price
margherita,£7.99
pepperoni,£8.99
four cheeses,£10.99
funghi,£8.99
import csv

with open('pizzas.csv', newline='') as f:

   reader = csv.reader(f)
 
   print(dir(reader))
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'dialect', 'line_num']

We can see that __getitems__ is not present in the list of attributes for the _csv.reader 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']

If we want to check if a specific attribute belongs to an object, we can check for membership using the in operator.

import csv

with open('pizzas.csv', newline='') as f:

   reader = csv.reader(f)

   print(type(reader))
 
   print('__getitem__' in dir(reader))
<class '_csv.reader'>
False

The variable reader is an object of the _csv.reader class. We can see that __getitem__ is not an attribute of the _csv.reader 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 _csv.reader object using indexing.

First, we will define a file called pizzas.csv, which contains the names and prices of pizzas in CSV format:

pizza,price
margherita,£7.99
pepperoni,£8.99
four cheeses,£10.99
funghi,£8.99

Next, import the csv module, read the file into our program using a context manager, and then create a reader object using the csv.reader() method. We will then try to access the second element of the reader object using the subscript operator, [].

import csv

with open('pizzas.csv', newline='') as f:

   reader = csv.reader(f)

   print(reader[1])

Let’s run the code to see what happens:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [4], in <cell line: 3>()
      3 with open('pizzas.csv', newline='') as f:
      5    reader = csv.reader(f)
----> 7    print(reader[1])

TypeError: '_csv.reader' object is not subscriptable

The error occurs because the reader variable is a _csv.reader object, which is an iterable containing the lines of the CSV file, which we can access using a for loop or calling the next() method. We are trying to access values in the _csv.reader object as though it were a list or another subscriptable object.

Solution

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

Let’s look at the revised code:

import csv

with open('pizzas.csv', newline='') as f:

   reader = list(csv.reader(f))

   print(reader[1])

Let’s run the code to see the result:

['margherita', '£7.99']

We successfully retrieved the first line of the CSV file. Each line returned by the reader object is a list containing the comma separated values.

The common way to read a CSV file with the reader object is to use a for loop. Let’s look at the revised code:

import csv

with open('pizzas.csv', newline='') as f:

   reader = csv.reader(f)

   next(reader)

   for line in reader:
       
       print(': '.join(line))

In the above code, we call the next() method to skip the field names in the CSV file, then use a for loop to iterate over the lines of the CSV file. We use the string join() method to join the items in the list into a single string. Let’s run the code to see the result:

margherita: £7.99
pepperoni: £8.99
four cheeses: £10.99
funghi: £8.99

Each line is a list of values and we can access each value using the subscript operator, []. Let’s look at getting the first value of each line:

import csv

with open('pizzas.csv', newline='') as f:

   reader = csv.reader(f)

   next(reader)

   for line in reader:
       
       print(line[0])

Let’s run the code to get the result:

margherita
pepperoni
four cheeses
funghi

We successfully retrieved the first value of each line in the CSV file.

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!

Research Scientist at Moogsoft | + posts

Suf is a research scientist at Moogsoft, specializing in Natural Language Processing and Complex Networks. Previously he was a Postdoctoral Research Fellow in Data Science working on adaptations of cutting-edge physics analysis techniques to data-intensive problems in industry. In another life, he was an experimental particle physicist working on the ATLAS Experiment of the Large Hadron Collider. His passion is to share his experience as an academic moving into industry while continuing to pursue research. Find out more about the creator of the Research Scientist Pod here and sign up to the mailing list here!

Follow the Research Scientist Pod on Social media!