Q&A library Python

How do I read and write JSON in Python?

Python Intermediate filesjsonserialisation

Short answer

Use json.load and json.dump for files, and json.loads and json.dumps for strings. The s versions work with strings, and common traps are non-serialisable types and forgetting that keys become strings.

The short version

Use json.load/json.dump to read and write files, and json.loads/json.dumps to work with strings. The rule for remembering which is which: the s versions deal with strings. JSON maps cleanly onto Python dicts and lists, but a few types do not serialise, and all keys come back as strings.

Strings versus files

import json

data = {"city": "Leeds", "orders": 3}

text = json.dumps(data)        # dict -> JSON string
back = json.loads(text)        # JSON string -> dict

The file versions read from or write to a file object directly.

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

with open("data.json") as f:
    data = json.load(f)

Making the output readable

By default dumps produces one compact line. Pass indent for a human-friendly layout.

json.dumps(data, indent=2)

This is worth doing for files a person might read or a diff might compare, because a compact single line is hard to inspect.

The non-serialisable trap

JSON only understands a limited set of types: strings, numbers, booleans, None, lists and dicts. Common Python objects like datetime, set, and NumPy or pandas types raise TypeError.

import datetime
json.dumps({"when": datetime.date(2021, 1, 1)})   # TypeError

Convert such values to a supported type first (a date to a string with isoformat(), a set to a list), or pass a default function that tells dumps how to handle them.

json.dumps({"when": datetime.date(2021, 1, 1)}, default=str)

Keys become strings

JSON object keys are always strings, so a dict with integer keys comes back with string keys after a round trip.

json.loads(json.dumps({1: "a"}))   # {'1': 'a'}, key is now a string

This surprises people who expect the integer key back. If you need integer keys, convert them yourself after loading.

Reading a JSON column into pandas

For tabular JSON, pandas.read_json or pandas.json_normalize turns records straight into a DataFrame, which is easier than looping. Use plain json for configuration and small structures, and the pandas helpers when the JSON is really a table of records.

Encoding for non-English text

If your data contains non-ASCII characters, pass ensure_ascii=False so they are written as themselves rather than as escape sequences, and open the file with encoding="utf-8". This keeps names and accented text readable in the output file.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project