Contact
Evil Genius SocietyHomeLearnForumLeaderboardSocialsMessages
← Back to module

Lesson 4 of 9

CSV only handles flat tables. JSON — JavaScript Object Notation — stores nested structures, which makes it the natural fit for the dictionaries and lists you built in Module 3. It's also the format most web APIs speak, which matters in Module 8.

import json

data = {"name": "Ada", "age": 36, "languages": ["Python", "C"]}
print(json.dumps(data))

The four functions

The json module has two pairs, and the s suffix means "string":

| Function | Does | | --- | --- | | json.dump(obj, file) | write an object to a file | | json.load(file) | read an object from a file | | json.dumps(obj) | object → string | | json.loads(string) | string → object |

Writing to a file

import json

data = {
    "name": "Ada",
    "age": 36,
    "languages": ["Python", "C"],
    "active": True,
}

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

with open("person.json") as f:
    print(f.read())

indent=2 pretty-prints it across multiple lines. Leave it out and you get one dense line — fine for machines, harder for humans.

Reading from a file

import json

with open("person.json", "w") as f:
    json.dump({"name": "Ada", "languages": ["Python", "C"]}, f)

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

print(type(data))
print(data["name"])
print(data["languages"][0])

What comes back is a real Python dictionary — index it, loop it, everything from Module 3.

Unlike CSV, JSON preserves types. Numbers come back as numbers, booleans as booleans, nested lists as nested lists.

Strings, not files

dumps/loads work with strings instead. You'll use these constantly in Module 8, because APIs send back JSON text:

import json

text = '{"name": "Ada", "age": 36}'
data = json.loads(text)
print(data["age"] + 1)

back_to_text = json.dumps(data)
print(back_to_text)

How Python types map

| Python | JSON | | --- | --- | | dict | object | | list, tuple | array | | str | string | | int, float | number | | True / False | true / false | | None | null |

Two things to watch. A tuple becomes a list — save (1, 2) and you load back [1, 2]. And sets and your own class instances can't be serialised at all:

import json

print(json.dumps({"tags": {"a", "b"}}))

That raises TypeError: Object of type set is not JSON serializable. Convert to a list first: list(my_set).

Saving a list of records

The most common real shape — exactly what the Module 3 contact book needed:

import json

contacts = [
    {"name": "Ada", "phone": "555-0100"},
    {"name": "Grace", "phone": "555-0199"},
]

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

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

print(len(loaded))
print(loaded[1]["name"])

That's persistence: the data outlives the program.

Try it yourself

Save a nested structure to JSON, load it back, and confirm the types survived.

Checkpoint

  • JSON stores nested data and preserves types; CSV is flat text.
  • dump/load work with files; dumps/loads work with strings.
  • indent=2 makes the output human-readable.
  • Tuples come back as lists; sets and custom objects raise TypeError.

Questions about this lesson

Log in to ask a question.