runtime
96 / 250
lesson 96 CSV JSON & JSONL · intermediate

Read CSV rows as dictionaries

`csv.DictReader` reads a CSV file one row at a time as a dictionary keyed by the header. It handles quoted commas for you, and every value it gives you is text.

You'll be able to
  • Explain why line.split(",") breaks on real CSV files and what csv does instead
  • Read rows with csv.DictReader from a file opened with newline=""
  • Convert the text values you calculate with, and skip rows that can't be converted
The idea

CSV looks simple: values separated by commas, one row per line. Then a product description contains a comma, and the file wraps it in quotes: 536378,22386,"JUMBO BAG, PINK POLKADOT",10,1.95. Splitting that line on commas gives six pieces instead of five, and every column after the description shifts.

The csv module follows the quoting rules. csv.DictReader(file) reads the first line as the header and gives you each following row as a dictionary from column name to value, so you write row["Quantity"] instead of remembering that quantity is column 4. Open the file with newline="" so the csv module sees the line endings itself (a quoted value is allowed to contain a line break).

CSV has no types: every value is text. "10" is a string until you call int.

Run each example to see what it prints. Running examples doesn't count toward progress.

example-1.py · A quoted comma stays in its column
import csv

with open("invoice_lines.csv", "w", encoding="utf-8", newline="") as out:
    out.write("Invoice,StockCode,Description,Quantity,Price\n")
    out.write('536378,22386,"JUMBO BAG, PINK POLKADOT",10,1.95\n')
    out.write("536378,21033,JUMBO BAG CHARLIE AND LOLA TOYS,10,2.95\n")

with open("invoice_lines.csv", encoding="utf-8", newline="") as source:
    for row in csv.DictReader(source):
        print(row["StockCode"], "|", row["Description"], "|", row["Quantity"])

Because every value is text, arithmetic on a CSV value fails or, worse, does something else: "10" * 2 is "1010". Convert at the point of use.

example-2.py · Adding up text
import csv

with open("payments.csv", "w", encoding="utf-8", newline="") as out:
    out.write("payment_id,amount\nPAY0000045,12.93\nPAY0001357,71.14\n")

total = 0
with open("payments.csv", encoding="utf-8", newline="") as source:
    for row in csv.DictReader(source):
        total += row["amount"]
print(total)

A typical job: read an export, keep the rows that matter, convert the numbers, and total them per category. This one totals delivered revenue per state from a Runtime Market orders export.

example-3.py · Delivered revenue per state
import csv

def revenue_by_state(path):
    revenue = {}
    with open(path, encoding="utf-8", newline="") as source:
        for row in csv.DictReader(source):
            if row["status"] != "delivered":
                continue
            state = row["ship_state"]
            revenue[state] = revenue.get(state, 0) + float(row["total"])
    return revenue

with open("orders.csv", "w", encoding="utf-8", newline="") as out:
    out.write("order_id,status,total,ship_state\n")
    out.write("O100043,delivered,12.93,NY\n")
    out.write("O101217,delivered,71.14,FL\n")
    out.write("O108024,cancelled,57.34,CO\n")
    out.write("O104839,delivered,142.77,FL\n")

for state, amount in revenue_by_state("orders.csv").items():
    print(state, f"{amount:.2f}")

When to use it: for any CSV that has a header row (most exports do). DictReader reads one row at a time, so it works on large files too. Mistakes to avoid: splitting lines on commas yourself, forgetting that every value is text, and comparing numbers as text ("9.99" > "10.00" is True).

Review
  • csv.DictReader(file) gives each row as a dictionary keyed by the header; quoted commas stay inside their value.
  • Open CSV files with encoding="utf-8", newline="".
  • Every value is text: convert with int/float where you calculate, and skip rows that can't be converted.
  • Next: write CSV files, header first.
Practise this

Loading your progress…

To master this lesson, solve both challenges without hints or the answer, and pass the concept check.

Read CSV rows as dictionaries — CSV JSON & JSONL · Runtime