Python Working with JSON Files

In the last lesson you learned Working with CSV Files. There you saved data in neat rows and columns. CSV is great for flat tables. But a lot of real data is not flat. It has nesting. Think of a user who has a name, some settings, and a list of friends all bundled together. For that kind of shape, the format you reach for is JSON. This lesson is about reading and writing it in Python.

πŸ€” Why JSON?

Think about the apps you use every day. When WhatsApp talks to its servers, or Netflix loads your watch list, the data flying back and forth is almost always JSON. Config files for your tools are often JSON too.

Here is the pain. You have a Python object in memory, like a dictionary of settings. The moment your program stops, that object is gone. You need a way to write it to a file as plain text. Then you need to read it back later in the same shape.

That is exactly what JSON does. JSON stands for JavaScript Object Notation. It is just a text format for structured data. Python ships with a built-in json module. It turns your objects into JSON text and back. So you do not have to do any of that work by hand.

🧩 What JSON Looks Like

JSON is plain text. But it is laid out in a way that holds structure. If you have seen a Python dictionary, JSON will feel familiar right away.

Here is a small piece of JSON describing a user.

{
"name": "Alex",
"age": 25,
"is_member": true,
"hobbies": ["reading", "cycling"]
}

Look at the pieces:

  • The curly braces hold a set of key and value pairs. This is a JSON object.
  • The square brackets hold a list of values. This is a JSON array.
  • Keys are always text in double quotes, like "name".
  • Values can be text, numbers, true or false, or even more objects and arrays inside.

So JSON is really just text that knows how to nest. That nesting is what makes it good for real data.

πŸ” The Python and JSON Mapping

Here is the part that makes the json module easy to trust. The two sides line up almost one to one. A Python value becomes a matching JSON value, and back again.

The mapping is worth keeping in front of you.

Python JSON
dict object (curly braces)
list array (square brackets)
str string
int and float number
True and False true and false
None null

The big ones to remember are the first two. A Python dictionary becomes a JSON object. A Python list becomes a JSON array. Get those two and the rest follows naturally.

πŸ“¦ dump, load, dumps, loads

The json module gives you these four functions. They sound similar, so people mix them up. But there is a simple way to keep them straight. Just ask yourself a couple of things. Are you going to a file or to a string? And are you saving or loading?

Here is the layout:

  • json.dump and json.load work with files.
  • json.dumps and json.loads work with strings. The extra s stands for string.
  • dump and dumps save, turning a Python object into JSON.
  • load and loads read, turning JSON back into a Python object.

Tip

The s at the end means string. dumps gives you a JSON string. loads reads from a JSON string. No s means it deals with a file instead.

πŸ’Ύ Saving to a File With json.dump

Let’s start with the most common job. You have a settings dictionary, and you want to save it to a file. The function for that is json.dump.

This program builds a small settings dict and writes it to a file called settings.json.

import json
settings = {
"username": "alex",
"theme": "dark",
"volume": 70,
"notifications": True
}
with open("settings.json", "w") as file:
json.dump(settings, file, indent=4)
print("Settings saved.")

Walk through it line by line:

  • import json brings in the built-in module. You need this at the top.
  • settings is an ordinary Python dictionary.
  • open("settings.json", "w") opens the file in write mode. The with block closes it for you when it is done.
  • json.dump(settings, file, indent=4) does the real work. It takes the dict, turns it into JSON text, and writes that text into the file.
  • indent=4 is optional. It spreads the JSON across lines with neat spacing, so a human can read it.

Output

Settings saved.

After running it, the file settings.json on disk holds this text.

{
"username": "alex",
"theme": "dark",
"volume": 70,
"notifications": true
}

Notice two small changes JSON made for us. The Python True became true, lowercase, because that is how JSON writes it. And the whole thing is laid out neatly thanks to indent=4.

Note

Without indent=4, the JSON gets written all on one line, like {"username": "alex", ...}. It still works perfectly. The indent is only there to make it pleasant for a human to read.

πŸ“‚ Loading From a File With json.load

Saving is only half the story. Later, maybe the next time the program runs, you want that settings dict back. That is json.load.

This program opens the file we just wrote and reads it back into a Python dictionary.

import json
with open("settings.json", "r") as file:
settings = json.load(file)
print(settings)
print("Theme is:", settings["theme"])
print("Volume is:", settings["volume"] + 5)

Here is what each part does:

  • open("settings.json", "r") opens the file in read mode.
  • json.load(file) reads the JSON text and rebuilds it as a real Python dictionary.
  • After that, settings is a normal dict again. So settings["theme"] works just like any dictionary lookup.

Output

{'username': 'alex', 'theme': 'dark', 'volume': 70, 'notifications': True}
Theme is: dark
Volume is: 75

This is the whole point. The volume came back as a real number 70, not the text "70". So settings["volume"] + 5 does actual math and gives 75. And True came back as a real Python True. The shape and the types survived the trip to the file and back.

🧡 Working With Strings: dumps and loads

Sometimes the JSON is not in a file at all. It is just text sitting in a variable. This happens a lot with APIs. A web service sends you back a string of JSON, and you need to turn it into a Python object. For that you use the string versions.

First, json.dumps turns a Python object into a JSON string you can hold in a variable.

import json
user = {"name": "Riya", "age": 30, "active": True}
text = json.dumps(user)
print(text)
print("Type is:", type(text))

json.dumps gives back a string instead of writing to a file. So text is now plain JSON text.

Output

{"name": "Riya", "age": 30, "active": true}
Type is: <class 'str'>

Now the other direction. json.loads takes a JSON string and builds a Python object from it.

import json
incoming = '{"name": "Arjun", "age": 28, "active": false}'
person = json.loads(incoming)
print(person)
print("Name:", person["name"])
print("Active:", person["active"])

The variable incoming is a string, the kind of thing an API would hand you. json.loads reads it and gives back a real dictionary.

Output

{'name': 'Arjun', 'age': 28, 'active': False}
Name: Arjun
Active: False

See how JSON false came back as Python False, with the capital F? The mapping table from earlier is working in reverse here.

⚠️ Common Mistakes

A few traps catch people again and again. Watch for these.

  • Mixing up the file and string versions. dump/load need a file object. dumps/loads need a string. Pass the wrong type and Python complains.
# ❌ Avoid: dumps expects to return a string, not write to a file
with open("data.json", "w") as file:
json.dumps(data, file)
# βœ… Good: dump (no s) writes to a file
with open("data.json", "w") as file:
json.dump(data, file)
  • Forgetting to import json. It is built in, but you still have to import it at the top of your file.

  • Using single quotes inside a JSON string. JSON keys and text values must use double quotes. Single quotes are valid Python but not valid JSON, so json.loads will crash on them.

# ❌ Avoid: single quotes are not valid JSON
bad = "{'name': 'Alex'}"
json.loads(bad) # crashes
# βœ… Good: double quotes inside the JSON
good = '{"name": "Alex"}'
json.loads(good)
  • Expecting JSON to save every Python type. JSON only knows the types in the mapping table. Things like a set or a datetime are not JSON values, so saving them directly will raise an error. Convert them to a list or a string first.

βœ… Best Practices

Keep these small habits and JSON stays easy.

  • Always open files with with open(...). It closes the file for you, even if something goes wrong partway.
  • Use indent=4 when a person will read the file. Skip it when only a program will read it, to keep the file small.
  • Remember the s rule. dumps and loads are for strings, dump and load are for files.
  • Keep your data as plain dicts, lists, strings, numbers, and booleans. Those map cleanly to JSON without any extra work.

🧩 What You’ve Learned

βœ… JSON is a plain-text format for structured data, used everywhere in APIs and config files.

βœ… A Python dictionary maps to a JSON object, and a Python list maps to a JSON array.

βœ… json.dump writes a Python object to a file, and json.load reads it back into a Python object.

βœ… json.dumps and json.loads do the same thing but with strings instead of files. The s means string.

βœ… Types survive the trip. Numbers come back as numbers, and True/False map to JSON true/false.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    A Python dictionary becomes which JSON type?

    Why: A Python dict maps to a JSON object (the curly-brace form), and a Python list maps to a JSON array.

  2. 2

    Which function writes a Python object into a file as JSON?

    Why: json.dump (no s) writes to a file. json.dumps returns a string, and the load functions read instead of write.

  3. 3

    What does the extra s in json.dumps and json.loads mean?

    Why: The s stands for string. dumps and loads work with JSON strings, while dump and load work with files.

  4. 4

    After json.load reads a JSON number like 70, what does Python give you?

    Why: json.load rebuilds the real Python types, so a JSON number comes back as an actual number you can compute with.

πŸš€ What’s Next?

You can now save and load structured data with JSON. Next we look at how Python finds your files in the first place. That way reading and writing them works no matter where your program runs.

File Paths

Share & Connect