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.