How to Work with JSON in Python
JSON (JavaScript Object Notation) is one of the most common formats for storing and exchanging data across applications and APIs. Python provides a built-in json module that makes it easy to parse, read, write, and manipulate JSON documents. This article covers JSON structure, parsing nested objects and arrays, working with files, and managing common JSON parsing errors.
1. Understanding JSON Structure
JSON is a lightweight, structured text format used to represent data as key-value pairs and arrays. A JSON document begins with either an object ({}) or an array ([]). Inside a JSON object, we can include zero, one, or many key-value pairs. When we define multiple key-value pairs, each one must be separated with a comma.
A key-value pair consists of a key on the left and a value on the right, separated by a colon (:). JSON keys must always be double-quoted strings, unlike Python, which allows single quotes. JSON values must be one of the supported data types listed below.
JSON Data Types
| JSON Data Type | Description |
|---|---|
| object | A collection of key-value pairs enclosed in {} |
| array | An ordered list of values inside [] |
| string | Text wrapped in double quotes "" |
| number | Integers or floating-point numbers |
| boolean | true or false without quotes |
| null | Represents an empty value using null |
JSON supports nesting, meaning objects can contain arrays, and arrays can contain objects. This makes JSON flexible enough to represent complex structures. Python’s json module can convert common Python data types into their JSON equivalents. The table below shows the mapping:
Python to JSON Data Type Mapping
| Python Type | JSON Equivalent |
|---|---|
| dict | object |
| list | array |
| tuple | array |
| str | string |
| int | number |
| float | number |
| True | true |
| False | false |
| None | null |
Note that Python lists and tuples both convert to JSON arrays. When converting JSON back to Python, arrays always become lists, meaning the original type may not be preserved.
Basic Parsing Example
import json
# Sample JSON string
json_string = '{"name": Thomas", "age": 25, "city": "New York"}'
# Parse JSON string into a Python dictionary
data = json.loads(json_string)
# Accessing values
print("Name:", data["name"])
print("Age:", data["age"])
print("City:", data["city"])
This example begins by importing the json module and defining a string that contains a JSON object. The json.loads() method converts the JSON string into a Python dictionary, allowing direct access to keys just as with any normal dictionary. The output shows how to retrieve specific fields (name,age, city). This simple pattern forms the foundation for all JSON parsing in Python.
Output
Name: Thomas Age: 25 City: New York
2. Nested JSON Objects Handling
JSON objects can contain other objects, forming a nested structure. These structures are common in configuration files, API responses, and hierarchical datasets. Accessing nested values requires chaining dictionary keys at each level.
import json
# Nested JSON string
nested_json_string = """
{
"person": {
"name": "Mr Fish",
"age": 30,
"address": {
"street": "123 Maple St",
"city": "Los Angeles"
}
}
}
"""
# Parse JSON string
data = json.loads(nested_json_string)
# Access nested values
print("Name:", data["person"]["name"])
print("Age:", data["person"]["age"])
print("Street:", data["person"]["address"]["street"])
Here, the person key contains another JSON object, and the address key is nested further. Accessing nested values simply involves chaining keys (e.g., data["person"]["name"]). This pattern is common when reading API responses where data is grouped hierarchically.
Output
Name: Mr Fish Age: 30 Street: 123 Maple St
3. Parsing JSON Arrays
JSON arrays are lists of items enclosed in square brackets. Each item can be a simple value or a nested JSON object. Python converts JSON arrays into lists, which can be iterated over.
import json
# JSON array string
people = """
[
{"name": "Thomas", "age": 25},
{"name": "Eve", "age": 30},
{"name": "John", "age": 22}
]
"""
# Parse JSON array
data = json.loads(people)
print(f"Total persons: {len(data)}")
# Loop through array
for person in data:
print(f"Name: {person['name']}, Age: {person['age']}")
The JSON array contains three objects, each representing a person. After parsing with json.loads(), the data becomes a list of dictionaries in Python. The len() function returns the number of items, and the loop prints each person’s details.
Output
Total persons: 3 Name: Thomas, Age: 25 Name: Eve, Age: 30 Name: John, Age: 22
4. Reading JSON From Files
JSON files are widely used to store configuration settings, structured logs, application data, and more. Python’s json.load() function allows you to parse JSON directly from a file.
import json
# Open JSON file and parse
with open("data.json", "r") as file:
data = json.load(file)
print(data["name"])
print(data["age"])
This example reads a JSON file using json.load(), which directly parses the file contents into Python objects without manually reading strings. Using with open(...) ensures the file is properly closed after reading. Accessing the parsed data works the same way as any dictionary.
Sample data.json
{
"name": "Thomas",
"age": 25,
"city": "New York"
}
Writing JSON to Files
To save JSON data to a file, Python provides the json.dump() function. This writes Python data as JSON directly to disk.
import json
data = {"name": "Bob", "age": 30, "city": "Los Angeles"}
with open("output.json", "w") as file:
json.dump(data, file, indent=4)
This code creates a JSON file named output.json containing the given data. Using indent ensures it is stored in a readable format. Writing JSON files is common when saving user preferences, logs, structured data, or exporting information.
Output (output.json)
{
"name": "Bob",
"age": 30,
"city": "Los Angeles"
}
5. Modifying JSON Data
Once JSON is parsed into Python objects, we can modify it just like any dictionary or list. This includes adding new fields, updating existing values, and removing elements entirely. These operations are useful when cleaning data, transforming API responses, updating configuration files, or preparing JSON before saving or sending it back to another service.
Adding an Element
We can add elements to a parsed JSON object (dictionary) by assigning new key-value pairs. If we’re working with arrays (lists), we can append new items.
import json
employee_json = """
{
"name": "Helen",
"role": "Developer",
"skills": ["Python", "SQL"]
}
"""
employee = json.loads(employee_json)
# Add new elements
employee["location"] = "Remote"
employee["skills"].append("Docker")
updated_json = json.dumps(employee, indent=4)
print(updated_json)
This example adds a new top-level field called location and appends a new skill ("Docker") to the existing list of skills. JSON parsed into Python structures behaves exactly like normal dictionaries and lists, so adding new keys or appending items works naturally. After making the changes, json.dumps() regenerates a formatted JSON string containing the new fields.
Output
{
"name": "Helen",
"role": "Developer",
"skills": [
"Python",
"SQL",
"Docker"
],
"location": "Remote"
}
Updating an Element
To update an existing value, overwrite it by assigning a new value to the corresponding key.
import json
employee_json = """
{
"name": "Helen",
"role": "Developer",
"skills": ["Python", "SQL"]
}
"""
employee = json.loads(employee_json)
# Update existing elements
employee["role"] = "Senior Developer"
employee["skills"][0] = "Advanced Python"
updated_json = json.dumps(employee, indent=4)
print(updated_json)
Here, the role field is updated from "Developer" to "Senior Developer", and the first skill is modified to "Advanced Python". Because JSON objects convert to Python dictionaries and arrays convert to lists, updating any part of the structure is simply direct assignment or list modification. The resulting JSON reflects the updated data.
Output
{
"name": "Helen",
"role": "Senior Developer",
"skills": [
"Advanced Python",
"SQL"
]
}
Deleting an Element
Python lets us remove JSON elements using del for dictionary keys or remove() / pop() for list items.
import json
employee_json = """
{
"name": "Helen",
"role": "Developer",
"skills": ["Python", "SQL", "Docker"],
"location": "Remote"
}
"""
employee = json.loads(employee_json)
# Delete elements
del employee["location"] # Remove a field
employee["skills"].remove("SQL") # Remove a list item
updated_json = json.dumps(employee, indent=4)
print(updated_json)
In this example, the location key is removed using del, while "SQL" is removed from the skills list using remove(). These operations work on Python structures but directly affect the resulting JSON when serialized back.
Output
{
"name": "Helen",
"role": "Developer",
"skills": [
"Python",
"Docker"
]
}
6. Handling JSON Parsing Errors
When working with JSON in Python, errors can occur for many reasons, such as invalid JSON formatting, incorrect data types, missing files, or a lack of file permissions. Python provides several exceptions that help us detect and recover from these problems. By wrapping our JSON operations inside try–except blocks, we can prevent our program from crashing and respond in a controlled way.
Using try–except allows our application to gracefully handle errors like malformed JSON, missing files, incorrect types, or restricted access while providing helpful feedback to users or logs.
Using try–except When Working With JSON
A try–except block lets us test a block of code and catch possible exceptions. Here is the basic pattern when working with JSON:
import json
try:
with open("data.json") as file:
data = json.load(file)
print("JSON loaded successfully")
except json.JSONDecodeError:
print("Error: The JSON file contains invalid syntax.")
except FileNotFoundError:
print("Error: The file does not exist.")
except PermissionError:
print("Error: You do not have permission to read the file.")
except TypeError:
print("Error: Incorrect data type was used.")
This structure ensures our program remains stable even when something goes wrong.
Common JSON Parsing Errors
Below are some of the most common JSON-related errors
Invalid JSON Syntax (json.JSONDecodeError)
A JSONDecodeError occurs when the JSON string is improperly formatted. JSON requires strict syntax rules: keys must be quoted, commas must be correctly placed, and strings must use double quotes.
import json
bad_json = '{ "name": "John", "age": 30,, }'
try:
data = json.loads(bad_json)
except json.JSONDecodeError as e:
print("JSONDecodeError occurred:", e)
Output
JSONDecodeError occurred: Expecting property name enclosed in double quotes: line 1 column 29 (char 28)
This error happens when the JSON data does not follow the required syntax rules. Fixing it often involves adding missing quotes, removing trailing commas, or correcting malformed structures.
Incorrect Data Type (TypeError)
This happens when we pass the wrong type into a JSON function.
import json
try:
json.loads(123) # expecting a string, not an integer
except TypeError as e:
print("TypeError occurred:", e)
Output
TypeError occurred: the JSON object must be str, bytes or bytearray, not int
json.loads() accepts only strings, bytes, or bytearrays, so the solution is to ensure you always pass a properly formatted JSON string when calling the function.
File Does Not Exist (FileNotFoundError)
A FileNotFoundError is raised when attempting to load a JSON file that does not exist at the provided path.
import json
try:
with open("missing.json", "r") as file:
data = json.load(file)
except FileNotFoundError as e:
print("File error:", e)
Output
File error: [Errno 2] No such file or directory: 'missing.json'
Make sure the file is located correctly or use an absolute path, and consider checking for its existence before attempting to read it.
Handling PermissionError (No Access to File)
A PermissionError occurs when Python finds the file but does not have permission to read it. This can happen with protected system files or files lacking read permissions.
import json
try:
with open("/protected/data.json", "r") as file:
data = json.load(file)
except PermissionError as e:
print("Permission error:", e)
Output
Permission error: [Errno 13] Permission denied: '/protected/data.json'
Even if a file exists, the operating system may block access for security reasons, so adjusting permissions, using user-accessible directories, or running the script with appropriate access rights ensures our program can read the file safely.
7. Conclusion
In this article, we explored how to parse, manipulate, and handle JSON data in Python, including understanding JSON structure, working with nested objects and arrays, reading and writing files, modifying data, and handling common errors. Using Python’s built-in json module with proper error handling allows Python developers to efficiently process JSON for APIs, applications, and configuration management.
8. Download the Source Code
This article covered how to parse JSON in Python with examples.
You can download the full source code of this example here: how to parse json in python



