The csv module handles the quirks of CSV files so you don't have to. Quoting, escaping, different delimiters—it's all managed for you.

Reading CSV Files

The basic pattern for reading:

import csv
 
with open('data.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)  # row is a list of strings

Always use newline='' when opening CSV files. This lets the csv module handle line endings correctly across platforms.

Reading as Dictionaries

When your CSV has headers, DictReader is more convenient:

import csv
 
with open('users.csv', newline='') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row['name'], row['email'])

Each row becomes a dictionary with column headers as keys.

Writing CSV Files

Writing is just as straightforward:

import csv
 
data = [
    ['name', 'age', 'city'],
    ['Alice', '30', 'NYC'],
    ['Bob', '25', 'LA'],
]
 
with open('output.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerows(data)

Writing Dictionaries

DictWriter for structured data:

import csv
 
users = [
    {'name': 'Alice', 'email': 'alice@example.com'},
    {'name': 'Bob', 'email': 'bob@example.com'},
]
 
with open('users.csv', 'w', newline='') as f:
    fieldnames = ['name', 'email']
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    
    writer.writeheader()
    writer.writerows(users)

Handling Different Dialects

Not all CSV files use commas. Handle tab-separated or semicolon-separated:

import csv
 
# Tab-separated
with open('data.tsv', newline='') as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader:
        print(row)
 
# Semicolon-separated (common in European locales)
with open('data.csv', newline='') as f:
    reader = csv.reader(f, delimiter=';')
    for row in reader:
        print(row)

Custom Dialects

Register your own dialect for consistent formatting:

import csv
 
csv.register_dialect('pipes', delimiter='|', quoting=csv.QUOTE_MINIMAL)
 
with open('data.txt', newline='') as f:
    reader = csv.reader(f, dialect='pipes')
    for row in reader:
        print(row)

Handling Quoted Fields

The csv module handles quoting automatically:

import csv
 
data = [
    ['name', 'bio'],
    ['Alice', 'She said, "Hello!"'],
    ['Bob', 'Line 1\nLine 2'],
]
 
with open('output.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerows(data)

Fields containing commas, quotes, or newlines get quoted automatically.

Skipping Headers

If you need to skip the header row:

import csv
 
with open('data.csv', newline='') as f:
    reader = csv.reader(f)
    next(reader)  # Skip header
    for row in reader:
        process(row)

Type Conversion

CSV readers return strings. Convert as needed:

import csv
 
with open('sales.csv', newline='') as f:
    reader = csv.DictReader(f)
    total = 0
    for row in reader:
        total += float(row['amount'])
    print(f"Total: ${total:.2f}")

Large Files

For memory-efficient processing, iterate row by row:

import csv
 
def process_large_csv(filename):
    with open(filename, newline='') as f:
        reader = csv.DictReader(f)
        for row in reader:
            yield transform(row)

Readers are iterators—they don't load the whole file.

When to Use csv vs pandas

Use csv when:

  • Simple read/write operations
  • Memory is constrained
  • You don't need data analysis features
  • Minimal dependencies matter

Use pandas when:

  • Complex data transformations
  • Statistical analysis
  • Merging multiple files
  • You're already in a data science context

The csv module is lightweight and has zero dependencies. For straightforward file processing, it's exactly what you need.

React to this post: