Skip to content

Python json — Parse & Serialize JSON

JSON (JavaScript Object Notation) is the most common format for exchanging data between programs, APIs, and config files. Python’s built-in json module converts between JSON text and Python objects — no installation needed.

quickstart.py
import json
 
data = {"name": "Ada", "age": 36, "skills": ["math", "code"]}
text = json.dumps(data)         # Python -> JSON string
print(text)                     # {"name": "Ada", "age": 36, "skills": ["math", "code"]}
 
back = json.loads(text)         # JSON string -> Python
print(back["skills"][0])        # math

The module has two pairs: one works with strings, the other with files.

FunctionDirectionWorks with
json.dumps(obj)Python → JSONA string (“dump string”).
json.loads(text)JSON → PythonA string (“load string”).
json.dump(obj, file)Python → JSONA file object.
json.load(file)JSON → PythonA file object.

Remember the s: dumps/loads end in s for string; dump/load are for files.

Serialization converts Python types to their JSON equivalents (and back):

PythonJSON
dictobject
list, tuplearray
strstring
int, floatnumber
True / Falsetrue / false
Nonenull

Note: tuples become JSON arrays, and JSON arrays always load back as lists — so a round-trip turns a tuple into a list.

dumps.py
import json
 
data = {"name": "Ada", "active": True, "score": None, "tags": ["a", "b"]}
 
# Compact (default)
print(json.dumps(data))
 
# Pretty-printed with indentation
print(json.dumps(data, indent=2))
 
# Sort keys alphabetically
print(json.dumps(data, sort_keys=True))
 
# Custom separators for the most compact output
print(json.dumps(data, separators=(",", ":")))

Common dumps / dump options:

OptionEffect
indent=nPretty-print with n spaces per level.
sort_keys=TrueOrder object keys alphabetically.
separators=(item, key)Control the item and key-value separators.
ensure_ascii=FalseKeep non-ASCII characters as-is (e.g. emoji, accents).
default=funcA fallback function to serialize unknown types.
unicode.py
import json
 
data = {"city": "São Paulo", "emoji": "🐍"}
print(json.dumps(data))                       # escapes non-ASCII
print(json.dumps(data, ensure_ascii=False))   # keeps São Paulo and 🐍 readable
loads.py
import json
 
text = '{"name": "Ada", "age": 36, "skills": ["math", "code"], "active": true}'
obj = json.loads(text)
 
print(type(obj))          # <class 'dict'>
print(obj["name"])        # Ada
print(obj["active"])      # True  (JSON true -> Python True)
print(obj["skills"][1])   # code

Use dump/load to read and write JSON files directly.

files.py
import json
 
config = {"theme": "dark", "version": 2, "plugins": ["a", "b"]}
 
# Write to a file
with open("config.json", "w", encoding="utf-8") as f:
    json.dump(config, f, indent=2)
 
# Read it back
with open("config.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)
 
print(loaded["theme"])    # dark
sketch What survives a JSON round-trip, and what quietly does not p5.js
JSON has fewer types than Python, so dumping and loading is not always the identity function. Dictionary keys are the sharp edge: JSON keys are strings, so an integer key comes back as a string and the dictionary you get is not the one you sent. Tuples come back as lists. Sets and tuple keys are refused outright. Every line here was run, and the identical column is a real comparison of the object before and after.

Invalid JSON raises json.JSONDecodeError (a subclass of ValueError). Always guard parsing of untrusted input.

errors.py
import json
 
bad = '{"name": "Ada", }'   # trailing comma is invalid JSON
 
try:
    json.loads(bad)
except json.JSONDecodeError as e:
    print("Could not parse:", e)

By default, json only knows the built-in types. For your own classes, pass a default function (or convert to a dict first).

custom.py
import json
from datetime import datetime
 
def encode(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Cannot serialize {type(obj).__name__}")
 
event = {"name": "launch", "when": datetime(2025, 1, 31, 9, 0)}
print(json.dumps(event, default=encode))
# {"name": "launch", "when": "2025-01-31T09:00:00"}
api_like.py
import json
 
response = '''
{
  "status": "ok",
  "users": [
    {"id": 1, "name": "Ada"},
    {"id": 2, "name": "Linus"}
  ]
}
'''
 
data = json.loads(response)
for user in data["users"]:
    print(user["id"], "->", user["name"])
# 1 -> Ada
# 2 -> Linus
  • Single quotes — JSON requires double quotes around keys and strings. "{'a': 1}" fails; use '{"a": 1}'.
  • Trailing commas are invalid in JSON (unlike Python).
  • True/None vs true/null — Python prints capitalized; JSON uses lowercase. The module handles the conversion for you, but watch for it when hand-writing JSON.
  • Non-serializable types (sets, datetimes, custom classes) raise TypeError unless you supply default.
  • Keys become strings — JSON object keys are always strings, so {1: "a"} serializes to {"1": "a"}.

Exercise 2 – Parse JSON and read a value

Section titled “Exercise 2 – Parse JSON and read a value”

Exercise 3 – Pretty-print with indentation

Section titled “Exercise 3 – Pretty-print with indentation”
  • json converts between JSON text and Python objects with four functions: dumps/loads (strings) and dump/load (files).
  • Python types map cleanly to JSON; tuples and JSON arrays both become lists on the way back.
  • Format output with indent, sort_keys, separators, and ensure_ascii.
  • Guard parsing with try/except json.JSONDecodeError.
  • Serialize custom types with a default function.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading