JSON in Python
JSON is a text format for structured data, and Python's standard json module reads and writes it. json.loads() turns a JSON string into Python values such as dictionaries and lists, and json.dumps() turns Python values back into a JSON string.
Key facts
json.loads('{"a": 1}')returns the dictionary{'a': 1}.json.dumps()writesTrue,FalseandNoneastrue,falseandnull.json.dump(data, f)writes JSON to an open file, andjson.load(f)reads it back.indent=2puts each item on its own line, indented two spaces per level.- Text that
json.loads()can't parse, such as{'a': 1}with single quotes, raisesjson.JSONDecodeError, which gives the line and column.
What is JSON in Python?
JSON is a text format for structured data, and the json module turns it into Python values. The module comes with Python, so import json is all the setup it needs.
import json
text = '{"name": "Ada", "age": 36, "langs": ["en", "fr"]}'
data = json.loads(text)
print(data["name"], data["langs"][1])
print(type(data))Ada fr <class 'dict'>
json.loads(), where the s stands for string, parsed the text. That means it read the JSON and built the matching Python value, here a dictionary. The key lookups from the dictionaries lesson work on it.
A JSON object is JSON's name for key-value pairs in curly braces, not an object made from a class. JSON objects become dictionaries, and JSON arrays, the values in square brackets, become lists.
Websites and apps exchange data as JSON, and config files often use it, because nearly every programming language can read and write it. The JSON to Python converter shows the Python version of any JSON you paste.
How do I convert Python data to a JSON string?
Pass the data to json.dumps(), and it returns a JSON string. Dictionaries, lists, tuples, strings, integers, floats, booleans and None all convert.
import json
user = {"name": "Ada", "admin": True, "email": None, "tags": ("a", "b")}
print(json.dumps(user)){"name": "Ada", "admin": true, "email": null, "tags": ["a", "b"]}The output uses JSON's spellings, so True became true and None became null, and every string is in double quotes. The tuple came out as a JSON array, the same as a list would, because JSON has no tuple type.
Turning Python data into JSON text is called serializing, and reading it back, as json.loads() does, is called deserializing.
How do I pretty-print JSON in Python?
Pass indent to json.dumps(), and each item goes on its own line. Adding sort_keys=True also puts the keys in order.
import json
user = {"name": "Ada", "age": 36}
print(json.dumps(user, indent=2, sort_keys=True)){
"age": 36,
"name": "Ada"
}indent=2 indents each level by two spaces, and indent=4 by four. sort_keys sorts by character code, not alphabetically, so "B" comes before "a" and "10" comes before "9".
How do I write a JSON file in Python?
Open the file for writing and pass it to json.dump() along with the data. dump(), without the s, writes straight to the file instead of returning a string.
import json
settings = {"theme": "dark", "font_size": 14}
with open("settings.json", "w", encoding="utf-8") as f:
json.dump(settings, f, indent=2)
with open("settings.json", encoding="utf-8") as f:
print(f.read()){
"theme": "dark",
"font_size": 14
}Open JSON files with encoding="utf-8" too. The JSON standard requires UTF-8 for data shared between systems, and the files lesson explains why text files need an encoding.
Python 3.14 added python -m json for checking a JSON file from a terminal. It prints the file formatted or reports the first error, and older versions use python -m json.tool instead.
python -m json settings.json
Run the command on your own computer in the folder that holds the file, with your file's name in place of settings.json. On macOS and Linux, type python3 instead of python.
How do I read a JSON file in Python?
Open the file and pass it to json.load(), which returns the parsed data. For a JSON object, that's a dictionary you can loop over and look up like any other.
import json
with open("scores.json", "w", encoding="utf-8") as f:
f.write('{"Ada": 90, "Grace": 85}')
with open("scores.json", encoding="utf-8") as f:
scores = json.load(f)
for name, score in scores.items():
print(name, score)Ada 90 Grace 85
Writing scores.json first lets the code run on its own. With a file that already exists, the with block that calls json.load() is all you need.
What is the difference between json.load() and json.loads()?
json.load() reads JSON from a file, and json.loads() reads it from a string. The same pattern separates dump(), which writes to a file, from dumps(), which returns a string.
| Function | Converts | Takes | Gives back |
|---|---|---|---|
json.loads(text) | JSON to Python | A string | Python data |
json.load(f) | JSON to Python | An open file | Python data |
json.dumps(data) | Python to JSON | Python data | A string |
json.dump(data, f) | Python to JSON | Python data and an open file | None, after writing to the file |
Use the string versions for JSON that arrives as text, such as a website's response, and the file versions for files on disk. json.load(f) does the same job as json.loads(f.read()).
How do JSON types map to Python types?
JSON objects load as dict, arrays as list, strings as str, booleans as bool and null as None. Numbers load as int or float, and json.dumps() converts the same way in the other direction.
| JSON | Example | Python type |
|---|---|---|
| Object | {"a": 1} | dict |
| Array | [1, 2] | list |
| String | "hi" | str |
| Whole number | 42 | int |
| Number with a decimal point or exponent | 4.5 | float |
| true and false | true | bool |
| null | null | None |
Two conversions don't survive a round trip. Tuples come back as lists, and keys that are numbers, booleans or None become strings, so the key 1 turns into '1'.
What causes a JSONDecodeError in Python?
json.loads() raises json.JSONDecodeError when it can't parse the text as JSON. Its message names the problem and gives the line and column where reading stopped.
import json
bad = "{'name': 'Ada'}"
try:
json.loads(bad)
except json.JSONDecodeError as e:
print("Invalid JSON:", e)Invalid JSON: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
JSON is stricter than Python. Keys and strings need double quotes, comments aren't allowed, and a comma after the last item is an error that Python 3.14 and 3.15 report as Illegal trailing comma before end of object (or array).
An empty string gives Expecting value: line 1 column 1 (char 0), and so does HTML that starts with <, such as a web server's error page. The JSON validator checks any JSON you paste and points at the first problem.
JSONDecodeError is a subclass of ValueError, so except ValueError catches it too. A traceback shows its full name, json.decoder.JSONDecodeError, which is the same class.
What does "not JSON serializable" mean in Python?
A value is not JSON serializable when the json module can't convert its type, such as a set. json.dumps() raises a TypeError for it, so convert a set to a list first, with sorted() if you want the items in a fixed order.
import json
data = {"tags": {"python", "json"}}
try:
json.dumps(data)
except TypeError as e:
print(e)
print(json.dumps({"tags": sorted(data["tags"])}))Object of type set is not JSON serializable
{"tags": ["json", "python"]}The same error appears for dates and for objects of your own classes. Turn them into strings, numbers, lists or dictionaries first, or pass default=str, which makes dumps() call str() on any value it can't convert.
Common mistakes with JSON in Python
Most of these four JSON mistakes in Python come from mixing up JSON text and the Python data it describes.
- TypeError: string indices must be integers, not 'str'. JSON text is still a string until you parse it, so
text["name"]fails. Calljson.loads()first. - json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes. Single quotes around a key cause it. Single quotes around a value, or Python's
TrueorNone, giveExpecting valueinstead. Write JSON with double quotes,trueandnull. - AttributeError: 'str' object has no attribute 'read'.
json.load("settings.json")got a file name, but it expects an open file. Open the file withopen()and pass the file object. - KeyError: 1. A dictionary key
1comes back from JSON as the string'1', sodata[1]finds nothing. Look up the string key, or convert the keys back withint()after loading.
The program below reads a key from the JSON text before parsing it. Change text["name"] to json.loads(text)["name"] and run it again.
import json
text = '{"name": "Ada"}'
print(text["name"])Traceback (most recent call last):
File "main.py", line 4, in <module>
print(text["name"])
~~~~^^^^^^^^
TypeError: string indices must be integers, not 'str'Exercise
Parse order into a new variable with json.loads(), add a "total" key for price times quantity, and print it with json.dumps(), so the output is the order with "total": 10.0 added at the end. The starter stops with a TypeError, because order is still a string.
import json
order = '{"item": "pen", "price": 2.5, "quantity": 4}'
order["total"] = order["price"] * order["quantity"]
print(json.dumps(order))
{"item": "pen", "price": 2.5, "quantity": 4, "total": 10.0}
Show the solution
import json
order = '{"item": "pen", "price": 2.5, "quantity": 4}'
data = json.loads(order)
data["total"] = data["price"] * data["quantity"]
print(json.dumps(data))
Quiz
This quiz has 5 questions. Pick an answer to see why it is right or wrong.
-
1What does this program print?
import json print(json.dumps({"ok": True, "note": None}))dumps() writes JSON, so True and None take their JSON spellings, true and null, without quotes. The version with single quotes is how print() shows a Python dictionary, not JSON.
-
2What does this program print?
import json print(type(json.loads("[1, 2, 3]")).__name__)The whole JSON text is an array, so loads() returns a list. It returns a dictionary only when the JSON is an object in curly braces.
-
3Which function writes JSON straight into an open file?
dump() takes the data and a file object and writes to the file. dumps() returns a string instead, and the two load functions read JSON rather than write it.
-
4What does this program print?
import json data = json.loads(json.dumps({1: "one"})) print(data)JSON keys are always strings, so dumps() turned the key 1 into "1", and loads() kept it as a string. print() shows the dictionary with single quotes, which rules out the version in double quotes.
-
5Which of these strings is valid JSON?
JSON needs double quotes around keys and strings and allows no comma after the last item. Single quotes are fine in Python but not in JSON.























