CSV files with the csv module
Overview
The `csv` module reads and writes comma-separated files correctly — handling quoting, embedded commas, and newlines that naive `line.split(',')` gets wrong. The `DictReader`/`DictWriter` variants map each row to a dict keyed by the header, which is what you usually want. import csv with open('people.csv', newline='', encoding='utf-8') as f: for row in csv.DictReader(f): print(row['name'], row['age']) # row is a dict with open('out.csv', 'w', newline='', encoding='utf-8') as f: w = csv.DictWriter(f, fieldnames=['name', 'age']) w.writeheader() w.writerow({'name': 'Ada', 'age': 36}) Always open CSV files with `newline=''` — the module handles line endings itself, and omitting it can produce blank rows on Windows. Note every value read from a CSV is a string; convert types yourself (`int(row['age'])`).
CSV is the universal export format for spreadsheets, databases, and data pipelines. The module handles the quoting edge cases that make hand-rolled `split(',')` parsers silently corrupt data.
Where used: Spreadsheet and database exports, Data ingestion / ETL scripts, Report generation
Why learn this
- CSV is the default interchange format for tabular data — you'll import and export it constantly.
- The module correctly handles quoted fields containing commas and newlines, which naive string splitting mangles.
Code walkthrough
import csv, io
raw = 'name,city\n"Smith, Jr.",Pune\nAda,Delhi\n'
reader = csv.DictReader(io.StringIO(raw))
for row in reader:
print(row['name'], '->', row['city'])
Focus: the first row's name stays "Smith, Jr." — the quoted comma is not split
Common mistakes
- Parsing CSV with line.split(','): A field like `"Smith, Jr."` legitimately contains a comma inside quotes. `split(',')` breaks it into two fields and corrupts every downstream column. The `csv` module respects quoting; hand-rolled splitting doesn't.
- Forgetting newline='' when opening: The csv module manages line endings itself. Opening without `newline=''` lets the OS translate newlines too, which on Windows inserts a blank row between every data row.
- Assuming values are typed: Every field read from CSV is a string — `row['age']` is `'36'`, not `36`. Comparing or doing math without converting (`int(...)`, `float(...)`) gives wrong results or type errors.
Glossary
- delimiter
- The character separating fields in a row, a comma by default. Example: `csv.reader(f, delimiter=';')`.
Recall questions
- Why use the csv module instead of `line.split(',')`?
- What does `csv.DictReader` give you for each row?
- Why should CSV files be opened with `newline=''`?
Understanding checks
Why does this fail or produce the wrong result?
`split(',')` splits on the comma inside the quoted name, producing three parts, so unpacking into two variables raises a ValueError (and the name is corrupted).
The comma inside `"Smith, Jr."` is data, not a field separator. `csv.reader`/`DictReader` honor the quotes and keep it as one field; `str.split` cannot.
After reading a CSV with DictReader, `row['age'] > 18` raises a TypeError. Why?
`row['age']` is a string like '25', and you can't compare a string to an int with `>`.
CSV stores everything as text, so every field arrives as a string. You must convert (`int(row['age']) > 18`) before numeric comparison or arithmetic.
Practice tasks
Sum a numeric column
Write CSV content with a header `name,score` and two rows, then read it back with DictReader and print the total of the `score` column. Remember values come back as strings.
Continue learning
Previous: Reading and writing files with open()