CSV Files with the csv Module
20 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)A CSV file holds a table as plain text: one row per line, values split by commas. Spreadsheets and reports use it everywhere. Splitting on commas by hand fails on tricky values, so Python ships the csv module.
Write and read rows
CSV (comma-separated values) is a plain text table: one row per line and one comma between values. The csv module reads and writes it safely.
Each row is a list of values. csv.writer turns a list into one line of the file. csv.reader does the reverse. Open the file with newline="" so the module controls line endings.
import csv
rows = [["name", "mark"], ["Asha", 82], ["Ravi", 67]]with open("marks.csv", "w", newline="") as f: csv.writer(f).writerows(rows)
with open("marks.csv", newline="") as f: for row in csv.reader(f): print(row)Example 1 · Write and read a table
import csv
rows = [["name", "mark"], ["Asha", 82], ["Ravi", 67]]with open("marks.csv", "w", newline="") as f: csv.writer(f).writerows(rows)
with open("marks.csv", newline="") as f: for row in csv.reader(f): print(row)['name', 'mark'] ['Asha', '82'] ['Ravi', '67']
What this code does
writerowswrites all rows. Numbers are turned into text on the way.- Reading shows every value as a string, including
'82'.
The reader gives each row as a list of strings. The mark 82 was a number when written but comes back as '82', because a CSV file only stores text. Convert with int(...) when you need to calculate.
Rows as dictionaries
DictReader is a csv class that reads each row as a dictionary. The first line of the file gives the keys, so you use names instead of positions.
Using row[1] for a column is hard to read. When the first line is a header, DictReader gives each row as a dictionary, so you ask for a column by its name.
import csv
with open("orders.csv", "w", newline="") as f: f.write("id,item,qty\n1,Pen,10\n2,Book,3\n")
total = 0with open("orders.csv", newline="") as f: for row in csv.DictReader(f): total += int(row["qty"]) print(row["item"], row["qty"])print("Items:", total)Example 2 · Order totals with DictReader
import csv
with open("orders.csv", "w", newline="") as f: f.write("id,price,qty\n1,250,2\n2,40,5\n")with open("orders.csv", newline="") as f: for row in csv.DictReader(f): print(row["id"], int(row["price"]) * int(row["qty"]))1 500 2 200
What this code does
- Columns are chosen by name, so the code still works if the column order changes.
- Both values are converted with
intbefore they are multiplied.
The header line becomes the dictionary keys. row["qty"] is still text, so int converts it before adding. DictWriter does the opposite and writes dictionaries as rows.
Commas inside a value
A name like Shah, Ravi holds a comma. Splitting on commas would cut it in two. The csv module wraps such values in quotes when writing, and unwraps them when reading.
import csv
with open("students.csv", "w", newline="") as f: csv.writer(f).writerow(["Shah, Ravi", 67])
with open("students.csv", newline="") as f: print(f.read().splitlines())
with open("students.csv", newline="") as f: print(next(csv.reader(f)))Example 3 · A comma inside a name
import csv
with open("students.csv", "w", newline="") as f: csv.writer(f).writerow(["Shah, Ravi", 67])with open("students.csv", newline="") as f: print(f.read().splitlines())with open("students.csv", newline="") as f: print(next(csv.reader(f)))['"Shah, Ravi",67'] ['Shah, Ravi', '67']
What this code does
- The writer added quotes around the name that holds a comma.
- The reader removed the quotes and returned two values.
The raw line is "Shah, Ravi",67, with quotes around the value that has a comma. Reading with csv.reader returns two values, not three. This is why you should not use line.split(",") on real CSV data.
Reader works on any lines
The reader does not care where lines come from. Give it a list of strings and it works the same. That is handy for tests and for text that arrives from input().
import csv
lines = ["name,mark", "Asha,82", "Ravi,67"]rows = list(csv.DictReader(lines))print(rows[0])print(sum(int(r["mark"]) for r in rows))Example 4 · Highest mark from a table
import csv
lines = ["name,mark", "Asha,82", "Ravi,67", "Meena,91"]best = max(csv.DictReader(lines), key=lambda r: int(r["mark"]))print(best["name"], best["mark"])Meena 91
What this code does
maxwith akeycompares the marks as numbers, not as text.- The reader accepts a list of lines, so no file is needed.
Each row is a dictionary. The generator in sum(...) converts each mark to an int and adds them.
Next step
Check your understanding
10 quick questions