JSON is the language of the internet. Every major API returns JSON. Knowing how to navigate, filter, and transform JSON data is one of the most practical skills in modern programming.
data['user']['address']['city'] Many API responses are deeply nested. Use .get() to avoid KeyError: city = data.get('user', {}).get('address', {}).get('city', 'Unknown')
Filtering Lists of Records
users = data['results'] # list of dicts ok_users = [u for u in users if u['state'] == 'OK'] List comprehensions work perfectly on JSON arrays of objects.
Pretty Printing
import json print(json.dumps(data, indent=2)) This formats JSON with indentation so it's readable. Essential for debugging API responses.
import json
# Simulated API response (like randomuser.me or similar)
api_response = """{
"results": [
{"name": "Alex Chen", "age": 16, "city": "Tulsa", "gpa": 3.8},
{"name": "Maria Garcia", "age": 17, "city": "OKC", "gpa": 3.5},
{"name": "James Wilson", "age": 16, "city": "Norman", "gpa": 3.2},
{"name": "Priya Patel", "age": 17, "city": "Tulsa", "gpa": 3.9},
{"name": "Tyler Brooks", "age": 15, "city": "Edmond", "gpa": 2.8}
],
"total": 5,
"page": 1
}"""
data = json.loads(api_response)
print(f"Total records: {data['total']}")
print(f"Page: {data['page']}")
print()
# Filter: only students with GPA >= 3.5
honor_roll = [s for s in data["results"] if s["gpa"] >= 3.5]
print("Honor Roll Students:")
for s in honor_roll:
print(f" {s['name']:<18} GPA: {s['gpa']} City: {s['city']}")
# Group by city
cities = {}
for s in data["results"]:
cities.setdefault(s["city"], []).append(s)
print("\nBy City:")
for city, students in sorted(cities.items()):
avg_gpa = sum(s["gpa"] for s in students) / len(students)
print(f" {city}: {len(students)} students, avg GPA {avg_gpa:.2f}")
✅ Check Your Understanding
1. What does json.loads(string) do?
2. How do you safely get a nested key that might not exist?