Modules Data And Errors
Working with CSV & JSON
name,age,city {"name": "Alice", "age": 25, "city": "Boston"}
Jr Codex Python Notes
Level: Intermediate Prerequisites: Chapter 2 Time to complete: ~25 minutes
Table of Contents
- Why These Two Formats?
- Reading CSV Files
- Writing CSV Files
DictReaderandDictWriter- Reading & Writing JSON
- JSON ↔ Python Type Mapping
- Handling Malformed Data
- Summary & Next Steps
1. Why These Two Formats?
CSV (Comma-Separated Values) and JSON (JavaScript Object Notation) are the two most common formats you'll encounter moving data in and out of Python programs — spreadsheets export CSV, APIs return JSON, and both reappear constantly in the ML/data modules later in this curriculum.
name,age,city {"name": "Alice", "age": 25, "city": "Boston"}
Alice,25,Boston
Bob,30,NYC ← CSV: tabular, row-based ← JSON: nested, key-value based
2. Reading CSV Files
import csv
with open("people.csv", "r", newline="") as file:
reader = csv.reader(file)
header = next(reader) # first row is usually the header
print(header) # ['name', 'age', 'city']
for row in reader:
print(row) # each row is a LIST of strings
# ['Alice', '25', 'Boston']Note: always pass newline="" when opening a CSV file — it prevents extra blank rows being inserted on some platforms due to how newlines are translated.
Every value comes back as a str, even numbers — you must convert manually:
with open("people.csv", "r", newline="") as file:
reader = csv.reader(file)
next(reader) # skip header
for row in reader:
name, age, city = row
age = int(age) # ✗ CSV has no types — you decide how to parse
print(f"{name} is {age} years old")3. Writing CSV Files
import csv
rows = [
["name", "age", "city"],
["Alice", 25, "Boston"],
["Bob", 30, "NYC"],
]
with open("output.csv", "w", newline="") as file:
writer = csv.writer(file)
writer.writerows(rows) # write all rows at once
# Or one row at a time:
# writer.writerow(["Charlie", 35, "LA"])4. DictReader and DictWriter
More convenient than plain reader/writer — rows come back as dictionaries keyed by the header, so you never have to remember column positions.
import csv
with open("people.csv", "r", newline="") as file:
reader = csv.DictReader(file) # automatically uses the first row as keys
for row in reader:
print(row) # {'name': 'Alice', 'age': '25', 'city': 'Boston'}
print(row["name"]) # 'Alice' — access by column NAME, not positionimport csv
people = [
{"name": "Alice", "age": 25, "city": "Boston"},
{"name": "Bob", "age": 30, "city": "NYC"},
]
with open("output.csv", "w", newline="") as file:
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader() # writes the header row
writer.writerows(people)Recommendation: default to DictReader/DictWriter for anything beyond a quick script — accessing row["name"] is far more readable and less error-prone than row[0].
5. Reading & Writing JSON
JSON maps closely onto Python's own dicts and lists — the json module converts between JSON text and native Python objects.
import json
# Parsing a JSON STRING into Python objects
json_string = '{"name": "Alice", "age": 25, "hobbies": ["reading", "hiking"]}'
data = json.loads(json_string) # "loads" = load from STRING
print(data) # {'name': 'Alice', 'age': 25, 'hobbies': [...]}
print(type(data)) # <class 'dict'>
print(data["name"]) # 'Alice'
# Converting Python objects INTO a JSON string
person = {"name": "Bob", "age": 30, "active": True}
json_string2 = json.dumps(person) # "dumps" = dump to STRING
print(json_string2) # '{"name": "Bob", "age": 30, "active": true}'
# Pretty-printed output
print(json.dumps(person, indent=2))# Reading/writing directly from/to a FILE (note: no "s" — load/dump, not loads/dumps)
import json
with open("data.json", "r") as file:
data = json.load(file) # "load" = load from FILE
with open("output.json", "w") as file:
json.dump(data, file, indent=2) # "dump" = dump to FILE| Function | Direction | Source/Target |
|---|---|---|
json.loads(s) | JSON string → Python object | string |
json.dumps(obj) | Python object → JSON string | string |
json.load(file) | JSON file → Python object | file |
json.dump(obj, file) | Python object → JSON file | file |
Memory trick: the "s" versions (loads/dumps) work with strings; the plain versions work with file objects.
6. JSON ↔ Python Type Mapping
import json
data = {
"name": "Alice", # JSON string ↔ Python str
"age": 25, # JSON number ↔ Python int/float
"active": True, # JSON true ↔ Python True
"spouse": None, # JSON null ↔ Python None
"hobbies": ["reading"], # JSON array ↔ Python list
"address": {"city": "Boston"}, # JSON object ↔ Python dict
}
print(json.dumps(data, indent=2))| JSON | Python |
|---|---|
object | dict |
array | list |
string | str |
number | int or float |
true / false | True / False |
null | None |
Important limitation: JSON has no tuple, set, or datetime type — json.dumps will raise a TypeError on a set, and will silently turn a tuple into a JSON array (which comes back as a list, not a tuple, when re-parsed).
7. Handling Malformed Data
Both formats fail loudly, but differently, on bad input — worth knowing before Chapter 4 covers proper exception handling:
import json
bad_json = '{"name": "Alice", "age": }' # missing value — malformed
data = json.loads(bad_json) # json.decoder.JSONDecodeError
# CSV with a missing column silently produces a shorter row — no error at all!
# Always validate row length or use DictReader, which surfaces this more clearly
# via missing keys (None values) instead of silent misalignment.Real-world CSV/JSON is rarely perfectly clean — Chapters 4–5 (Exception Handling) build the tools to handle exactly this kind of malformed input gracefully instead of crashing.
8. Summary & Next Steps
Key Takeaways
csv.reader/csv.writerwork with plain lists;csv.DictReader/csv.DictWriterwork with dicts keyed by column name — prefer the Dict versions for readability.- Every CSV value comes back as a
str— you must convert types (int(),float()) manually. json.loads/json.dumpswork with strings;json.load/json.dumpwork with file objects — the "s" marks the string variant.- JSON maps cleanly onto Python's
dict/list/str/int/bool/None— but has no native tuple, set, or datetime support.
Concept Check
- What's the difference between
csv.readerandcsv.DictReader? - Why does
json.loads('{"age": 25}')["age"]return anint, but every value fromcsv.readercomes back as astr? - What's the mnemonic for remembering
loads/dumpsvsload/dump?
Next Chapter
→ Chapter 4: Exception Handling
Jr Codex — 1-on-1 Personalized Coaching | Back to Module Index