CSV (comma-separated values) is a common format for spreadsheets and data exchange. Python’s built-in csv module reads and writes CSV without extra dependencies. This guide shows how to read rows as lists or as dictionaries (when the first row is a header), how to write CSV from lists or dicts, and how to avoid common pitfalls like extra blank lines on Windows or wrong encodings. For tabular data in memory see lists and dictionaries; for JSON see read and write JSON.

1. When to use the csv module

Use csv when you have a file with comma-separated (or other delimiter) columns and you want to iterate row by row. For heavy analysis or many transformations, Pandas is often easier; for one-off scripts or small files, csv is enough. The module handles quoting and escaping so you do not have to split on commas by hand. If the file uses a different delimiter (e.g. tab), pass delimiter='\t' to csv.reader or csv.writer.

2. Read CSV: rows as lists

Open the file in text mode with an explicit encoding (e.g. utf-8), create a csv.reader, and iterate. Each row is a list of strings. The first row is often the header; you can skip it or use it to build column names. If the file is missing you get FileNotFoundError—see file handling for paths and encoding.

import csv

with open("data.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

3. Read CSV with headers: DictReader

If the first row contains column names, use csv.DictReader. Each row is a dictionary keyed by the header names. Access with row['name']; missing keys raise KeyError, so use row.get('name', '') if a column might be absent.

import csv

with open("data.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"], row["age"])

4. Write CSV: rows as lists

Use csv.writer and writerows. Open the file in 'w' with newline='' to avoid extra blank lines on Windows. Always pass encoding='utf-8' (or the encoding you need) so non-ASCII characters are written correctly.

import csv

rows = [
    ["name", "age", "city"],
    ["Alice", "30", "NYC"],
    ["Bob", "25", "LA"],
]
with open("output.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(rows)

5. Write CSV with headers: DictWriter

When you have a list of dictionaries, use csv.DictWriter. Pass fieldnames in the order you want columns. Call writeheader() once, then writerows(data). If a dict is missing a key in fieldnames, you can pass extrasaction='ignore' to skip extra keys.

import csv

data = [
    {"name": "Alice", "age": 30, "city": "NYC"},
    {"name": "Bob", "age": 25, "city": "LA"},
]
fields = ["name", "age", "city"]
with open("output.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=fields)
    writer.writeheader()
    writer.writerows(data)

6. Delimiters, quoting, and encoding

For tab-separated files use delimiter='\t'. The default quoting handles fields that contain commas; for strict control use quoting=csv.QUOTE_MINIMAL (default) or csv.QUOTE_ALL. If you read a file that is not UTF-8, pass the correct encoding (e.g. encoding='latin-1'). Wrong encoding can cause UnicodeDecodeError; see the Errors section for decoding issues.

7. Quick reference and next steps

  • Read as lists → csv.reader
  • Read as dicts (header row) → csv.DictReader
  • Write from lists → csv.writer + writerows
  • Write from dicts → csv.DictWriter + writeheader + writerows

From here try read and write JSON for API-style data, or parse CSV with Pandas for analysis. For file paths and errors see file handling and FileNotFoundError.