CodingNic

File I/O

Working with JSON

File I/O 20 min read

Working with JSON

Objectives

By the end of this chapter, you should be able to:

  • Explain what JSON is and where it shows up
  • Read and write JSON files with the json module
  • Convert between JSON strings and Python objects

💡 Why this matters: JSON is the format most APIs speak, and a common choice for config files and saved application data. You’ve already seen it come back from an API response, now you’ll read and write it yourself.

What Is JSON?

JSON (JavaScript Object Notation) is a lightweight, text-based format for structured data. It maps closely onto Python’s own dictionaries and lists:

json
{
  "name": "Erin",
  "age": 29,
  "skills": ["Python", "SQL"],
  "active": true
}

Objects ({}) become dictionaries, arrays ([]) become lists, and strings, numbers, booleans, and null map directly onto Python’s str, int/float, bool, and None.

Reading a JSON File

The json module handles the conversion for you. json.load() reads a file object and returns a Python object. Say data.json contains:

json
{
  "name": "Erin",
  "age": 29,
  "skills": ["Python", "SQL"],
  "active": true
}
python
import json

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

print(data)         # {'name': 'Erin', 'age': 29, 'skills': ['Python', 'SQL'], 'active': True}
print(type(data))   # <class 'dict'>, just like any other Python value
print(data["name"]) # Erin, access it the same way you would any dict

Writing a JSON File

json.dump() writes a Python object out as JSON:

python
import json

person = {
    "name": "Jordan",
    "age": 31,
    "skills": ["Python", "Docker"],
}

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

Pass indent=2 to get readable, multi-line output instead of one long line, handy for files a human might open:

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

Converting Without a File: loads and dumps

Sometimes you have JSON as a plain string already (from an API response, for instance) rather than in a file. json.loads() (load-string) parses a JSON string directly into a Python object, and json.dumps() (dump-string) does the reverse:

python
import json

json_string = '{"name": "Maya", "age": 27}'
data = json.loads(json_string)
print(data["name"])  # Maya

python_dict = {"name": "Priya", "age": 33}
print(json.dumps(python_dict))  # {"name": "Priya", "age": 33}

This is exactly what’s happening under the hood when you call .json() on a requests response: it’s parsing the response body’s JSON string into a Python dictionary for you.

A Quick Comparison with CSV

JSON and CSV solve a similar problem, persisting structured data, but fit different shapes of data. CSV is a great match for uniform, tabular rows (like a spreadsheet); JSON handles nested and irregular structures far more naturally, since a JSON value can itself contain lists and dictionaries several layers deep:

python
import json

person = {
    "name": "Sam",
    "address": {"city": "Austin", "zip": "78701"},
    "hobbies": ["chess", "hiking"],
}
print(json.dumps(person, indent=2))
text
{
  "name": "Sam",
  "address": {
    "city": "Austin",
    "zip": "78701"
  },
  "hobbies": [
    "chess",
    "hiking"
  ]
}

A CSV row can’t naturally hold a nested address dictionary or a hobbies list. It’s flat by design; JSON isn’t.

Try It

  1. Write a Python dictionary describing something in your own life, and save it to a .json file with json.dump().
  2. Read that file back with json.load() and confirm you get an equal dictionary.
  3. Take a JSON string (write one by hand, or copy one from an API response) and parse it with json.loads().

Recap

  • JSON maps closely onto Python’s own data structures: objects become dicts, arrays become lists.
  • json.load()/json.dump() read and write JSON files; json.loads()/json.dumps() convert to and from JSON strings directly, without a file.
  • indent=2 (or any number) makes json.dump() output human-readable instead of a single line.

Next lesson: put file I/O into practice with a set of exercises.