A large portion of Python applications have something to do with data, it either retrieves data, alters data or processes data in another way. Most of the time this data will be stored in some sort of database, but there are times when a quick solution is necessary and in those cases, CSV files are perfect. CSV files are also perfect for sampling data or displaying data that will not be accessed programmatically, for example, possible leads.

Table of contents

Python is known for its extensive collection of libraries that make your job 10 times easier and of course, it also has a library dedicated to handling CSV files, the csv python module. This package can be found in the standard library, so you do not need to install anything. We’ll start off by importing this package

import csv

Writing CSV files

The CSV library has two ways of writing data to CSV files. Both have their own use cases and you will probably have to use both of them at some point.

I’ll start by discussing the csv.writer function. This is the most used option with ~1.000.000 usages on GitHub, versus ~50.000 usages for the second option.

csv.writer

Here you can see a quick example that should speak for itself. In the example script, Python will open the demo.csv' file and write two new rows to it, with one being the header.

file = open('demo.csv', 'w+', newline='')
writer = csv.writer(
    file,
    delimiter=',',
    quotechar='|',
    quoting=csv.QUOTE_MINIMAL
)
writer.writerow(['stock', 'price', 'cost', 'profit'])
writer.writerow(['21', '121.34', '45.34', '76'])
~ demo.csv
stock,price,cost,profit
21,121.34,45.45,76

This is about as simple as it gets, however, there are a few things you should probably remember:

  • The newline argument: this should always be '' when opening a file which the csv package will work with, to write the rows without a new line every row.
  • The quoting argument: this specifies which fields should be quoted, there are a few options you can choose from:
    • csv.QUOTE_ALL: All fields will be quoted
    • csv.QUOTE_MINIMAL: Only fields containing the delimiter or quotechar will be quoted.
    • csv.QUOTE_NONNUMERIC: The writer will quote all fields containing text and it converts all numbers to float values
    • csv.QUOTE_NONE: No fields will be quoted, the writer instead escapes delimiters. If you use this value, you also need to provide the escapechar argument.

This function only has one required argument, which is the file object, but it has a couple of other optional arguments:

  • delimiter: This argument specifies which delimiter the writer will use. It defaults to ',', but you can set it to any other character.
  • quotechar: This specifies which character will be used for quoting. It defaults to '"'
  • escapechar: This specifies the character that will be used to escape the delimiter if quoting is not being used. It defaults to nothing.

csv.DictWriter

The other option we could go with is the DictWriter class. This class provides you with a little bit more structure and is probably less error-prone, as you’ll see in this example.

Another thing you’ll probably notice is the extra argument called fieldnames. This is a required argument for the DictWriter class. This argument should contain a list of all column names. These will be used to map the values correctly. You should use the DictWriter.writeheaders() function to write the column names.

file = open('demo.csv', 'w+', newline='')
writer = csv.DictWriter(file, fieldnames=['stock', 'price', 'cost', 'profit'])
writer.writeheaders()
writer.writerow(
    {
        'stock': '21',
        'price': '121.34',
        'cost': '45.34',
        'profit': '76.00'
    }
)
~ demo.csv
stock,price,cost,profit
21,121.34,45.34,76.00

As you can see, this is a bit of a bulkier approach, but there certainly are advantages versus the csv.writer function. The main advantage with this approach is that you can’t really mess up the order in which you enter the values since it will automatically map the correct value to the right column, this is especially handy when you have a file with a dozen or maybe even dozens of columns.

I have made this mistake a lot of times and believe me, it’s a pain to find out why there is this one value that just isn’t correct, whatever you do.

Reading CSV files

Just as with writing, we have two options to choose from when reading a CSV file in Python. Here we also have a normal csv.reader function and a csv.DictReader class. In general, these two options have very much in common with their writing counterparts.

For the upcoming examples, we will use the file below as an example.

~ example.csv
stock, price, cost, profit
21, 121.34, 45.34, 76
13, 100, 50, 50
32, 140, 90, 50

csv.reader

This function is relatively simple and follows the same concept as csv.writer, it also accepts the same arguments as the csv.writer function. This small example should speak for itself.

file = open('example.csv', 'r')
reader = csv.reader(file, delimiter=',')

for counter, row in enumerate(reader):
    if counter == 0:
        print('Fieldnames: {}'.format(', '.join(row))
    else:
        print('Stock: {stock}tPrice: {price}tCost: {cost}tProfit {profit}'.format(row[0], row[1], row[2], row[3], row[4])) 

file.close()

And here is the output it will generate

Fieldnames: stock, price, cost, profit
stock: 21    price: 121.34    cost: 45.34    profit: 76
stock: 13    price: 100.00    cost: 50.00    profit: 50.00
stock: 32    price: 140.00    cost: 90.00    profit: 50.00

Each row returned by iterating over the reader object will return a list of strings that contain the column values. The first row returned will contain the column names.

If the CSV file has a non-default quotechar, you need to use the optional quotechar argument, when calling the csv.reader function.

csv.DictReader

Again, this class is very similar. Below is a very simple example that shows exactly what you can do with the class. The output should speak for itself.

file = open('example.csv', 'r')
reader = csv.DictReader(file, delimiter=',')

for row in reader:
    print(row)

And again the output this script will generate:

{'stock': '21', 'price': '121.34', 'cost': '45.34', 'profit': '76.00'}
{'stock': '13', 'price': '100.00', 'cost': '45.34', 'profit': '76.00'}
{'stock': '32', 'price': '140.00', 'cost': '90.00', 'profit': '50.00'}

The class grabs the fieldnames from the first line in the CSV file. If the file does not have those, you can specify them by passing on the optional fieldnames argument.

Conclusion

You should now know the basics of reading and writing CSV files in Python. In almost all use cases, the standard csv library will be enough, however, if you work with a lot of data, you might want to use pandas instead. We’ve already discussed writing and reading csv files with pandas before.

If you have any questions left about writing to csv files with Python or reading from csv files with Python, feel free to leave a comment and I’ll do my best to reply as soon as possible.