Skip to Content
Course content

259: The csv Module in Depth

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was reviewing a PR for a junior dev who was building a simple import tool for a client's product catalog. He had used line.split(',') to parse the CSV file. It worked perfectly during the first ten minutes of testing. Then, the client uploaded a real file containing a product called "Industrial Drill, Heavy Duty". Because that product name contained a comma, the split() method created an extra column, shifted all the subsequent data to the right, and crashed the database import with a type error. He spent the rest of the afternoon trying to write a complex Regular Expression to "fix" the splitting logic.

That's the exact moment I told him to stop and look at the csv module. When you're dealing with data exchange, "simple" files are rarely simple. Between quoted fields, different line endings, and varying delimiters, trying to parse CSVs manually is a recipe for a 3:00 AM debugging session.

Handling the Quoting Nightmare

The csv.reader object is your first line of defense. It doesn't just split by a character; it understands the RFC 4180 standard, which means it knows that if a comma is inside double quotes, it should be treated as part of the text, not as a column separator. I always recommend using it as an iterator to keep your memory footprint low, especially if you're dealing with massive datasets.

import csv

# Imagine 'products.csv' has a row: 101,"Industrial Drill, Heavy Duty",29.99
with open('products.csv', mode='r', newline='', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
        # row is a list: ['101', 'Industrial Drill, Heavy Duty', '29.99']
        print(f"Product: {row[1]} | Price: {row[2]}")

Notice the newline='' argument in open(). Don't skip this. The csv module handles its own newline translation; if you let Python's open() do it too, you'll often end up with mysterious blank lines between your data rows on Windows machines.

Mapping Data with DictReader and DictWriter

While index-based access (like row[1]) is fast, it's fragile. If the client adds a "Category" column to the middle of the CSV, your entire script breaks. This is where DictReader becomes a lifesaver. It uses the first row of the file as keys, turning every subsequent row into a dictionary.

import csv

with open('products.csv', mode='r', newline='', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        # Now we use the column name, which is much more readable
        print(f"Item: {row['ProductName']} - SKU: {row['SKU']}")

Writing data is just as streamlined. If you use DictWriter, you define the fieldnames upfront. I personally prefer this over the standard csv.writer because it forces you to be explicit about which columns you are actually exporting, preventing those dreaded "shifted column" errors in the output file.

Taming Non-Standard Delimiters and Dialects

In the real world, you'll encounter "CSVs" that aren't actually comma-separated. You'll find TSVs (tab-separated) or files from European legacy systems that use semicolons because commas are used as decimal points. You don't need a different library for this; you just need to define the delimiter.

If you find yourself repeatedly configuring the same set of parameters (delimiter, quoting style, line terminator), you can create a csv.Dialect. It's essentially a named configuration profile that you can pass into your reader or writer. It keeps your code clean and ensures consistency across different modules of your application.

import csv

# Handling a semicolon-separated file from a legacy system
with open('legacy_data.csv', mode='r', newline='') as f:
    reader = csv.reader(f, delimiter=';', quotechar='"')
    for row in reader:
        print(row)



📋 Practical Task

Exercise: The Messy Logistics Log Cleaner

You've been handed a logistics log file called shipments.log. The file is "CSV-like," but it uses a pipe (|) as a delimiter and occasionally wraps fields in single quotes (') instead of double quotes.

Your Task: Write a Python script that does the following:

  • Reads the shipments.log file using the csv module.
  • Handles the pipe delimiter and the single-quote character.
  • Filters out any rows where the "Status" column is marked as 'Cancelled'.
  • Writes the remaining "Active" or "Shipped" rows into a new file called cleaned_shipments.csv using standard comma delimiters and double-quote formatting.

Sample input data for shipments.log:
ID|Customer|Status|Weight
101|'Acme Corp'|'Shipped'|15.5
102|'Globex'|'Cancelled'|2.0
103|'Soylent Co'|'Active'|45.2

Rating
0 0

There are no comments for now.

to be the first to leave a comment.