Advanced

Reading JSON files

JSON is text with structure. Parsing turns that text into values, and the moment you parse is where a file stops being bytes.

What you will see

3

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Parse and inspect JSON.

1

Value from an object.

import json data = json.loads("{\"n\": 3}") print(data["n"])

Before you run it, say out loud what it will print. Then open the answer.

What it prints
3
2

Line of a bad parse.

import json try: json.loads("{bad}") except json.JSONDecodeError as e: print(e.lineno)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
1
3

Default for a missing key.

import json data = json.loads("{\"a\": 1}") print(data.get("b", 0))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0
4

Length of a top list.

import json data = json.loads("[1, 2, 3]") print(len(data))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
3

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

JSON text is parsed into values once. A broken file names a line, and missing keys need a chosen default.
1 read the text
↓
2 parse to values
↓
3 use the values
↓
4 report a bad parse
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

import json sets nothing on screen
data = json.loads("{\"n\": 3}") sets nothing on screen
print(data["n"]) 3
Why this works
Parse at the boundary

Parse when the text enters and keep values after that. Every later comparison on raw text is a bug waiting to happen.

A broken file is a state

A file that fails to parse is a real condition. Report the path and the line, then decide whether to continue.

Examples

Parse once

import json
text = "{\"n\": 3}"
data = json.loads(text)
print(data["n"])

One parse gives values you can index. Text comparisons on the raw file do not.

A file that is not valid

import json
try:
    json.loads("{bad}")
except json.JSONDecodeError as e:
    print(e.lineno)

The error names the line. A broken file is a report, not a crash.

Save it back

import json
data = {"n": 3}
out = json.dumps(data, indent=2)
print(len(out))

indent makes the file readable to a person. Same data, more bytes.

Keys can be missing

import json
data = json.loads("{\"a\": 1}")
print(data.get("b", 0))

get with a default keeps a missing key from raising. Decide the default on purpose.

A list at the top

import json
data = json.loads("[1, 2, 3]")
print(len(data))

The top value can be a list. Code that assumes an object fails on the first row.

Numbers stay numbers

import json
data = json.loads("{\"n\": 3}")
print(type(data["n"]).__name__)

JSON keeps types. Text formats that only carry strings lose that.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← When the file is missing
Previous Lesson
When the file is missing
Next Lesson
CSV rows
CSV rows →