Working with JSON and CSV
Plain text files store sentences. Real applications store structured data — and two formats run the world: JSON (the language of APIs and configs) and CSV (the language of spreadsheets). Python reads and writes both in a few lines.
JSON — dictionaries as files
JSON (JavaScript Object Notation) looks exactly like Python dicts and lists — because it was designed to be universal:
{
"name": "Aarav",
"age": 16,
"skills": ["python", "streamlit"],
"topper": true
}
Python’s json module converts between JSON text and Python objects:
| JSON | Python |
|---|---|
object {} |
dict |
array [] |
list |
| string | str |
| number | int / float |
| true / false | True / False |
| null | None |
Saving data with json.dump
import json
student = {
"name": "Aarav",
"age": 16,
"skills": ["python", "streamlit"],
}
with open("student.json", "w") as f:
json.dump(student, f, indent=2) # dump = write Python → JSON file
The indent=2 makes the file human-readable (pretty-printed). Open student.json and you’ll see neatly formatted JSON.
Loading data with json.load
import json
with open("student.json") as f:
data = json.load(f) # load = read JSON file → Python
print(data["name"]) # Aarav
print(data["skills"][0]) # python
print(type(data)) # <class 'dict'> — a real Python dict again!
That’s the full round trip: dict → file → dict. The loaded value is a real Python dictionary — index it, loop it, modify it, exactly like the ones you’ve built by hand.
The persistence pattern (the one from the to-do app)
import json
import os
FILE = "tasks.json"
def load_tasks():
if os.path.exists(FILE): # first run? no file yet
with open(FILE) as f:
return json.load(f)
return [] # fresh start
def save_tasks(tasks):
with open(FILE, "w") as f:
json.dump(tasks, f, indent=2)
# the app loop
tasks = load_tasks()
tasks.append("learn JSON")
save_tasks(tasks)
print(tasks)
Run it twice — the task list grows. This is how apps remember between sessions, and it’s the exact pattern from the to-do lesson, now explained fully.
json.dumps / json.loads — strings, not files
The s versions work with strings instead of files (d = dump string, s = load string):
text = json.dumps(student, indent=2) # dict → JSON string
print(text)
back = json.loads(text) # JSON string → dict
print(back["name"])
dumps is how you’d send JSON over a network or embed it in an API request.
CSV — the spreadsheet format
CSV (Comma-Separated Values) is what Excel, Google Sheets, and every data export speak:
name,age,grade
Aarav,16,A
Diya,15,A
Kabir,16,B
Python’s csv module handles the parsing (including the messy edge cases like commas inside values):
import csv
# Write
with open("students.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["name", "age", "grade"]) # header
writer.writerow(["Aarav", 16, "A"])
writer.writerow(["Diya", 15, "A"])
# Read
with open("students.csv") as f:
reader = csv.reader(f)
for row in reader:
print(row) # each row is a list: ['Aarav', '16', 'A']
The newline="" in the write open is a required quirk on some systems — include it by habit. Each row arrives as a list of strings — numbers included, so convert as needed.
DictReader — CSV with named columns
import csv
with open("students.csv") as f:
reader = csv.DictReader(f) # uses the header row as keys
for row in reader:
print(row["name"], "— grade", row["grade"])
DictReader turns each row into a dictionary keyed by the header — no more remembering that column 1 is age. For anything beyond tiny files, prefer it.
Common Errors & Fixes
json.decoder.JSONDecodeError— the file isn’t valid JSON (truncated write, hand-edited badly). The file is corrupted; regenerate it.KeyErrorafter json.load — the JSON lacks that key;.get()it or fix the source.- CSV rows all in one cell in Excel — you wrote with plain
f.writeinstead ofcsv.writer; let the module handle commas and quotes. - Blank lines between CSV rows — missing
newline=""in the open.
✅ Checkpoint
- Which functions convert dict→file and file→dict? (json.dump / json.load)
- What’s
json.dumpsfor? (Dict → JSON string, no file involved) - Why
os.path.existsbefore load? (First run has no file — return a fresh default) - What does
csv.DictReadergive you per row? (A dict keyed by the header names)
Module 8 checkpoint reached — errors handled, files read and written, data persisting.
Next module: Object-Oriented Python — the mindset behind every big codebase.