JSON & CSV

Most data you'll exchange with other programs arrives as JSON (from web APIs and config files) or CSV (from spreadsheets and databases). Python's standard library reads and writes both, converting them to and from ordinary dictionaries and lists.

JSON basics

PY json_basics.py
import json

user = {"name": "Ana", "age": 31, "admin": True, "tags": ["python", "sql"], "manager": None}

text = json.dumps(user)
print(text)

back = json.loads(text)
print(back["tags"][0], type(back))
Output
{"name": "Ana", "age": 31, "admin": true, "tags": ["python", "sql"], "manager": null}
python <class 'dict'>

json.dumps ("dump string") converts Python data to JSON text; json.loads ("load string") parses JSON text. Notice the translations: True → true, None → null, single quotes → double quotes.

PythonJSON
dictobject
list, tuplearray
strstring
int, floatnumber
True / False / Nonetrue / false / null

Pretty printing

PY pretty.py
import json

config = {"server": {"host": "localhost", "port": 8080}, "debug": False}
print(json.dumps(config, indent=2, sort_keys=True))
print(json.dumps({"city": "São Paulo"}, ensure_ascii=False))
Output
{
  "debug": false,
  "server": {
    "host": "localhost",
    "port": 8080
  }
}
{"city": "São Paulo"}

indent makes JSON readable; ensure_ascii=False keeps non-English characters as-is instead of escaping them.

Reading and writing JSON files

PY json_files.py
import json
from pathlib import Path

settings = {"theme": "dark", "font_size": 14, "recent": ["a.txt", "b.txt"]}

with open("settings.json", "w", encoding="utf-8") as f:
    json.dump(settings, f, indent=2)

with open("settings.json", encoding="utf-8") as f:
    loaded = json.load(f)

loaded["font_size"] += 2
print(loaded)

data = json.loads(Path("settings.json").read_text(encoding="utf-8"))
print(data == settings)
Output
{'theme': 'dark', 'font_size': 16, 'recent': ['a.txt', 'b.txt']}
True

Without the "s", json.dump and json.load work directly with file objects.

Handling invalid JSON and unsupported types

PY json_errors.py
import json
from datetime import date

try:
    json.loads("{'single': 'quotes'}")
except json.JSONDecodeError as err:
    print("Invalid JSON:", err.msg, "at position", err.pos)

event = {"name": "Launch", "date": date(2026, 11, 1)}
try:
    json.dumps(event)
except TypeError as err:
    print("TypeError:", err)

print(json.dumps(event, default=str))
Output
Invalid JSON: Expecting property name enclosed in double quotes at position 1
TypeError: Object of type date is not JSON serializable
{"name": "Launch", "date": "2026-11-01"}

JSON only supports the types in the table above. The default function is called for anything else — default=str is a quick fix for dates, decimals and similar values.

Reading CSV

PY csv_read.py
import csv

with open("people.csv", "w", encoding="utf-8", newline="") as f:
    f.write('name,city,score\nAna,Lisbon,91\n"Silva, Ben",Porto,78\nCleo,Faro,85\n')

with open("people.csv", encoding="utf-8", newline="") as f:
    for row in csv.reader(f):
        print(row)

with open("people.csv", encoding="utf-8", newline="") as f:
    rows = list(csv.DictReader(f))

print(rows[1]["name"], "-", rows[1]["city"])
print(sum(int(r["score"]) for r in rows))
Output
['name', 'city', 'score']
['Ana', 'Lisbon', '91']
['Silva, Ben', 'Porto', '78']
['Cleo', 'Faro', '85']
Silva, Ben - Porto
254

The csv module correctly handles quoted fields containing commas, which a simple line.split(",") would break. DictReader uses the header row as keys, giving one dictionary per row. Every value is read as a string — convert numbers yourself. Open CSV files with newline="", as the csv documentation recommends.

Writing CSV

PY csv_write.py
import csv

orders = [
    {"id": 1, "customer": "Ana", "total": 120.5},
    {"id": 2, "customer": "Ben, Jr.", "total": 35.0},
]

with open("orders.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["id", "customer", "total"])
    writer.writeheader()
    writer.writerows(orders)

with open("orders.csv", encoding="utf-8") as f:
    print(f.read(), end="")
Output
id,customer,total
1,Ana,120.5
2,"Ben, Jr.",35.0

The writer adds quotes automatically where needed. Use csv.writer with writerow([...]) for plain lists instead of dictionaries.

A typical pipeline: CSV in, JSON out

PY pipeline.py
import csv
import json
from collections import defaultdict

with open("sales.csv", "w", encoding="utf-8", newline="") as f:
    f.write("region,product,amount\nnorth,tea,30\nsouth,cake,45\nnorth,cake,20\nsouth,tea,15\n")

totals = defaultdict(float)
with open("sales.csv", encoding="utf-8", newline="") as f:
    for row in csv.DictReader(f):
        totals[row["region"]] += float(row["amount"])

print(json.dumps(totals, indent=2))
Output
{
  "north": 50.0,
  "south": 60.0
}

For larger tabular datasets, the pandas library (see the pandas course) offers far more powerful tools, but the standard library covers everyday needs.

Try it yourself

Try it yourself
Console output