How to Read a JSON File in Python
JSON (JavaScript Object Notation) is one of the most common data formats you'll encounter when working with APIs, configuration files, databases, and web services. Python makes reading JSON files straightforward — but the right approach depends on your data structure, file size, and what you plan to do with the data afterward.
What Is a JSON File?
A JSON file stores data as structured text using key-value pairs, arrays, and nested objects. It's human-readable and language-agnostic, which is why it's become a universal standard for data exchange.
A typical JSON file might look like this:
{ "name": "Alice", "age": 30, "languages": ["Python", "JavaScript"], "active": true } Python's built-in json module handles this format natively — no installation required.
The Standard Way: Using Python's Built-in json Module
The most common method uses open() to read the file and json.load() to parse it into a Python object.
import json with open("data.json", "r") as file: data = json.load(file) print(data) What's happening here:
import jsonloads Python's built-in JSON libraryopen("data.json", "r")opens the file in read modejson.load(file)parses the file contents and returns a Python dictionary (or list, depending on the JSON structure)- The
withstatement automatically closes the file after reading — always preferred over manually callingfile.close()
Once loaded, you access values just like any Python dictionary:
print(data["name"]) # Output: Alice print(data["languages"][0]) # Output: Python JSON to Python: How Types Are Mapped 🗂️
Understanding how JSON types convert to Python types prevents a lot of confusion:
| JSON Type | Python Type |
|---|---|
object{} | dict |
array[] | list |
string"" | str |
number (int) | int |
number (float) | float |
true / false | True / False |
null | None |
This mapping is automatic — json.load() handles the conversion without any extra steps.
Reading a JSON String Instead of a File
If your JSON data is already in memory as a string (common when receiving API responses), use json.loads() instead — the s stands for string:
import json json_string = '{"name": "Alice", "age": 30}' data = json.loads(json_string) print(data["age"]) # Output: 30 The distinction matters:
json.load()— reads from a file objectjson.loads()— reads from a string
Handling Encoding and File Paths
Specifying Encoding
If your JSON file contains non-ASCII characters (accented letters, Unicode symbols, etc.), specify the encoding explicitly:
with open("data.json", "r", encoding="utf-8") as file: data = json.load(file) UTF-8 is the standard encoding for JSON files per the JSON specification, but files created on Windows systems sometimes use other encodings. Omitting this argument on some systems can cause UnicodeDecodeError.
Using File Paths
For files in different directories, pass the full or relative path:
with open("/users/alice/documents/data.json", "r") as file: data = json.load(file) Using Python's pathlib module gives you more flexibility across operating systems:
from pathlib import Path import json file_path = Path("data") / "config.json" with open(file_path, "r") as file: data = json.load(file) Reading JSON Files with Nested Structures
Real-world JSON is often nested — objects inside objects, or lists of objects. Accessing nested values requires chaining keys and indexes:
{ "user": { "profile": { "city": "Toronto" } } } city = data["user"]["profile"]["city"] print(city) # Output: Toronto For deeply nested or inconsistent data, .get() is safer than direct key access because it returns None instead of raising a KeyError if a key doesn't exist:
city = data.get("user", {}).get("profile", {}).get("city", "Unknown") Handling Errors When Reading JSON
Two common errors appear when reading JSON files:
FileNotFoundError — the file path is wrong or the file doesn't exist:
try: with open("data.json", "r") as file: data = json.load(file) except FileNotFoundError: print("File not found. Check the path.") json.JSONDecodeError — the file content isn't valid JSON (trailing commas, missing quotes, and comments are common culprits):
try: with open("data.json", "r") as file: data = json.load(file) except json.JSONDecodeError as e: print(f"Invalid JSON: {e}") When the Standard Approach Isn't Enough
For most use cases — reading config files, processing API responses, loading small datasets — the built-in json module is all you need.
But the variables in your project may push you toward different tools:
- Large JSON files (hundreds of MB or more) can exhaust memory with
json.load(). Libraries likeijsonallow streaming — parsing the file incrementally without loading everything at once. - Tabular JSON data (lists of records with consistent keys) is often better handled by pandas using
pd.read_json(), which loads data directly into a DataFrame for analysis. - Strict schema validation requirements call for libraries like
jsonschema, which verify that loaded data matches an expected structure before your code processes it. - JSONL files (JSON Lines format, where each line is a separate JSON object) require reading line by line rather than loading the whole file.
The right tool shifts depending on file size, data shape, downstream processing needs, and how much control you need over error handling. What works cleanly for a 10KB config file may create serious problems when applied to a 2GB data export. 🔍