Python csv — Read & Write CSV
CSV (Comma-Separated Values) is the universal format for tabular data — spreadsheets, exports, datasets. The csv module reads and writes it correctly, handling quoting, commas inside fields, and newlines that naive string splitting would get wrong.
import csv
import io
# Read rows from CSV text
text = "name,age\nAda,36\nBob,25"
reader = csv.reader(io.StringIO(text))
for row in reader:
print(row)
# ['name', 'age']
# ['Ada', '36']
# ['Bob', '25']Always open files with
newline=""when usingcsv. This lets the module handle line endings itself and prevents blank rows on Windows.
The four tools
Section titled “The four tools”| Tool | Direction | Row shape |
|---|---|---|
csv.reader(file) | Read | Each row is a list. |
csv.writer(file) | Write | You pass lists. |
csv.DictReader(file) | Read | Each row is a dict keyed by header. |
csv.DictWriter(file, fieldnames) | Write | You pass dicts. |
Writing with csv.writer
Section titled “Writing with csv.writer”import csv
rows = [
["name", "city"],
["Ada", "London"],
["Bob", "New York, NY"], # comma inside a field is handled automatically
]
with open("people.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["title", "year"]) # one row
writer.writerows(rows) # many rowsThe module quotes fields that contain commas, quotes, or newlines, so "New York, NY" stays a single field.
Reading with csv.reader
Section titled “Reading with csv.reader”import csv
with open("people.csv", "r", newline="", encoding="utf-8") as f:
reader = csv.reader(f)
header = next(reader) # pull the header row off first
print("Header:", header)
for row in reader:
print(row) # each row is a list of stringsEvery value read from CSV is a string. Convert numbers yourself:
int(row[1]),float(row[2]).
DictReader — rows as dictionaries
Section titled “DictReader — rows as dictionaries”DictReader uses the first row as keys, so you access columns by name instead of position.
import csv
import io
text = "name,age,city\nAda,36,London\nBob,25,NYC"
reader = csv.DictReader(io.StringIO(text))
for row in reader:
print(row["name"], "is", row["age"])
# Ada is 36
# Bob is 25DictWriter — write dictionaries
Section titled “DictWriter — write dictionaries”DictWriter needs fieldnames; call writeheader() to emit the header row.
import csv
people = [
{"name": "Ada", "age": 36},
{"name": "Bob", "age": 25},
]
with open("out.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["name", "age"])
writer.writeheader()
writer.writerows(people)Custom delimiters and dialects
Section titled “Custom delimiters and dialects”Not every “CSV” uses commas. Pass delimiter for TSV (tabs), semicolons, or pipes.
import csv
import io
tsv = "name\tage\nAda\t36"
reader = csv.reader(io.StringIO(tsv), delimiter="\t")
print(list(reader)) # [['name', 'age'], ['Ada', '36']]| Parameter | Controls |
|---|---|
delimiter | Field separator (default ,). |
quotechar | Character used to quote fields (default "). |
quoting | When to quote (csv.QUOTE_MINIMAL, QUOTE_ALL, …). |
escapechar | Escape character for special chars. |
Common pitfalls
Section titled “Common pitfalls”- Missing
newline=""— causes blank rows between every record on Windows. - Forgetting values are strings —
row["age"] + 1fails; convert withint(...)first. DictWriterwithoutwriteheader()— produces a file with no header row.- Mismatched
fieldnames— a dict key not infieldnamesraisesValueError.
Practice Exercises
Section titled “Practice Exercises”Exercise 1 – Parse CSV text
Section titled “Exercise 1 – Parse CSV text”Exercise 2 – Sum a numeric column
Section titled “Exercise 2 – Sum a numeric column”Exercise 3 – Write rows to CSV text
Section titled “Exercise 3 – Write rows to CSV text”Summary
Section titled “Summary”- The
csvmodule handles quoting and embedded commas/newlines that manual splitting breaks. - Use
reader/writerfor lists,DictReader/DictWriterfor dicts keyed by header. - Open files with
newline=""and an explicitencoding. - Remember every read value is a string — convert numbers yourself.
- Set
delimiterfor TSV and other separated formats.
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading