Skip to Content
Course content

97: Working with CSV Files

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

Let's start with a piece of code that looks perfectly fine on the surface. Imagine you're writing a script to log some user data to a CSV file. You've got your list of users, you're using the csv module, and everything seems to be working. But when you open the resulting file in a text editor, you notice something annoying: there's a blank line between every single row of data.

import csv

users = [
    ["Alice", "Engineering"],
    ["Bob", "Marketing"],
    ["Charlie", "Sales"]
]

with open("users.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerows(users)

The Mystery of the Double Newline

If you run this on Windows, you'll likely see those empty rows. It's a classic "gotcha." Here is what's happening: the csv.writer handles its own newline characters (specifically \r\n). However, Python's open() function, by default, uses "universal newline mode," which translates \n into the system's default line separator. On Windows, that means it sees the \n from the CSV writer and adds another \r, effectively doubling the line break.

The fix is simple, but it's one of those things you only learn once you've spent twenty minutes staring at a CSV file wondering why it's half-empty. You need to pass newline='' to the open function.

# The Correct Way
with open("users.csv", "w", newline='') as f:
    writer = csv.writer(f)
    writer.writerows(users)

By setting newline='', we tell Python not to mess with the line endings, letting the csv module handle them exclusively. I always include this by default now; it saves a lot of headache.

Stop Counting Columns Manually

Most beginners start by using csv.reader, which returns each row as a list. That's fine for a file with two columns, but imagine a CSV with 30 columns. Writing row[14] in your code is a nightmare—you'll spend half your day counting commas in a text editor just to figure out which index corresponds to "Shipping Address."

Instead, I want you to get comfortable with csv.DictReader. It treats the first row of your CSV as headers and turns every subsequent row into a dictionary. This makes your code significantly more readable and much more resilient if the column order in the source file changes.

import csv

with open("employees.csv", "r") as f:
    reader = csv.DictReader(f)
    for row in reader:
        # Instead of row[0], we use the actual header name
        print(f"Employee {row['Name']} works in {row['Department']}")

Writing Data with DictWriter

If you're reading data as dictionaries, it only makes sense to write them that way too. The csv.DictWriter class allows you to pass in a list of fieldnames (your headers) and then write rows as dictionaries. The biggest hurdle here is remembering that DictWriter doesn't automatically write the header row for you—you have to call a specific method for that.

import csv

data = [
    {"Name": "Alice", "Role": "Dev", "Level": 3},
    {"Name": "Bob", "Role": "Designer", "Level": 2},
]

fields = ["Name", "Role", "Level"]

with open("staff.csv", "w", newline='') as f:
    writer = csv.DictWriter(f, fieldnames=fields)
    
    # Don't forget this part, or your CSV will have no headers!
    writer.writeheader() 
    writer.writerows(data)

One quick tip: if your dictionary has more keys than the fieldnames list, DictWriter will raise a ValueError. If you want it to just ignore the extra keys, you can pass extrasaction='ignore' to the constructor. It's a lifesaver when you're dealing with messy API responses that you're dumping into a CSV.




📋 Practical Task

Inventory Value Calculator

You have been handed a CSV file named inventory.csv with the following content:

Product,Quantity,PricePerUnit
Laptop,10,1200
Mouse,50,25
Keyboard,30,75
Monitor,15,300

Write a Python script that does the following:

  1. Reads inventory.csv using csv.DictReader.
  2. Calculates the total value for each item (Quantity × PricePerUnit).
  3. Calculates the grand total value of the entire inventory.
  4. Prints each product and its total value, followed by the grand total.
Expected Output:
Laptop: $12000
Mouse: $1250
Keyboard: $2250
Monitor: $4500
Grand Total: $20000
Rating
0 0

There are no comments for now.

to be the first to leave a comment.