Advertisement
🔧 Intermediate

Python JSON – Reading, Writing, and Converting JSON Data

JSON (JavaScript Object Notation) is the universal data format for APIs and configuration files. Python's built-in json module makes it trivial to parse JSON into Python dicts/lists and serialise Python objects back to JSON strings.

⏱️ 20 min read🎯 Intermediate📅 Updated 2026

Parsing JSON Strings – json.loads()

json.loads() converts a JSON string into Python objects.

Python
import json

json_string = '''{
    "name": "Alice",
    "age": 30,
    "skills": ["Python", "SQL"],
    "active": true
}'''

data = json.loads(json_string)

print(data["name"])    # Alice
print(data["age"])     # 30
print(data["skills"])  # ['Python', 'SQL']
print(type(data))      # <class 'dict'>
▶ Output
Alice 30 ['Python', 'SQL'] <class 'dict'>

Converting to JSON String – json.dumps()

json.dumps() converts Python objects to a JSON string.

Python
import json

python_dict = {
    "name": "Bob",
    "scores": [95, 87, 92],
    "passed": True,
    "grade": None
}

# Basic conversion
json_str = json.dumps(python_dict)
print(json_str)

# Pretty-printed with indentation
pretty = json.dumps(python_dict, indent=2)
print(pretty)
▶ Output
{"name": "Bob", "scores": [95, 87, 92], "passed": true, "grade": null} { "name": "Bob", "scores": [95, 87, 92], "passed": true, "grade": null }

Reading and Writing JSON Files

Use json.load() and json.dump() for file operations.

Python
import json

# Write JSON to file
data = {"users": [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]}

with open("data.json", "w") as f:
    json.dump(data, f, indent=2)

# Read JSON from file
with open("data.json", "r") as f:
    loaded = json.load(f)

print(loaded["users"][0]["name"])  # Alice
Advertisement

Real-World: Processing API Responses

Most web APIs return JSON. Here is the standard pattern for consuming one.

Python
import json
import urllib.request

# Fetch from a public API
url = "https://api.github.com/users/python"

with urllib.request.urlopen(url) as response:
    data = json.loads(response.read())

print(data["name"])         # Python
print(data["public_repos"]) # number of repos
print(data["followers"])    # follower count

Python ↔ JSON Type Mapping

JSON has a limited set of types. Python converts automatically.

Python
# Python → JSON type mapping:
# dict     → object   {}
# list     → array    []
# str      → string   ""
# int/float→ number   42, 3.14
# True     → true
# False    → false
# None     → null

# Verify:
print(json.dumps({"a": True, "b": None, "c": [1,2]}))
▶ Output
{"a": true, "b": null, "c": [1, 2]}

JSON in Python: dumps, loads, and the Type Mismatches

JSON is the lingua franca of APIs. Python's json module converts between JSON text and Python objects — but the two type systems don't line up perfectly, and the gaps cause real bugs.

import json
data = {"name": "Ann", "active": True, "scores": [9, 8]}

text = json.dumps(data, indent=2)   # Python → JSON string (serialize)
back = json.loads(text)             # JSON string → Python (parse)
Python↔ JSON
dictobject
True / False / Nonetrue / false / null
tuplearray (→ comes back a list!)

Three gotchas:

  • Dict keys become strings. json.dumps({1: "a"}) gives {"1": "a"} — integer keys round-trip back as strings.
  • datetime/set/bytes aren't serializabledumps raises TypeError. Convert them first (e.g. date.isoformat()) or pass a custom default= function.
  • Tuples become lists on the round trip — JSON has no tuple type.

Use json.dump(obj, file)/json.load(file) (no "s") to read/write files directly. For untrusted input, wrap loads in try/except json.JSONDecodeError.

🏋️ Practical Exercise

Convert between Python and JSON:

  1. Parse a JSON string into a Python dict with json.loads().
  2. Convert a dict back to a JSON string with json.dumps(..., indent=2).
  3. Write a dict to a .json file with json.dump() and read it back with json.load().
  4. Inspect how Python types map to JSON types (e.g. Nonenull).

🔥 Challenge Exercise

Simulate processing an API response: start with a JSON string representing a list of users (each with name, age, and a list of roles). Parse it, filter to users over 18, add a computed field, and write the result back out as pretty-printed JSON to a file. Handle a malformed JSON string with try/except json.JSONDecodeError. Bonus: serialize a datetime using a custom default function.

📋 Summary

  • JSON is a lightweight, language-independent data format used heavily in APIs.
  • json.loads parses a string; json.load parses from a file object.
  • json.dumps produces a string; json.dump writes to a file object.
  • Python dicts ↔ JSON objects, lists ↔ arrays, Nonenull, Truetrue.
  • Use indent= for readable output and sort_keys=True for deterministic key order.
  • Custom types need a default function or custom encoder; invalid JSON raises JSONDecodeError.

Interview Questions on JSON

  • What is JSON and why is it widely used?
  • What is the difference between json.loads and json.load?
  • What is the difference between json.dumps and json.dump?
  • How do Python types map to JSON types?
  • How do you pretty-print JSON output?
  • How do you serialize a non-standard type like datetime?
  • What exception is raised when parsing invalid JSON?

FAQ

What is the difference between loads/dumps and load/dump? +

The s stands for “string”. loads/dumps work with JSON strings in memory, while load/dump read from or write to a file object directly.

How do I make JSON output readable? +

Pass indent=2 (or 4) to json.dumps/json.dump for pretty-printed, indented output. Add sort_keys=True if you want keys in a consistent order.

Why can’t I serialize a datetime or a custom object? +

JSON only supports a fixed set of types. For others, pass a default function (e.g. converting datetimes to ISO strings) or write a custom JSONEncoder. Otherwise you get a TypeError.

What error do I get from invalid JSON? +

Parsing malformed JSON raises json.JSONDecodeError (a subclass of ValueError), which reports the position of the problem so you can wrap the call in try/except.