Reading JSON from Files with json.load()
json.loads() transforms a JSON string into a Python data structure by parsing the text and building corresponding lists, dictionaries, and primitive values.
Try it: Parsing JSON into Python
How json.loads() reads JSON text token by token and builds Python dicts, lists, strings, numbers, True/False and None, how an access path like data["users"][0]["name"] walks that structure, and what json.dumps() writes back.
How it works
- The scanner reads the next token: a brace or bracket, a string in double quotes, a number, true / false / null, or a ',' / ':' delimiter.
- '{' starts a Python dict and '[' a list; both are pushed on a parse stack until their closing '}' or ']'.
- Inside a dict every key must be a double-quoted string followed by ':' and a value; items are separated by ','.
- Anything else stops the parse with JSONDecodeError, reporting the message, line, column and character position.
- The access path is applied one subscript at a time: dicts take keys (KeyError if missing), lists take integer indexes (IndexError if out of range).
- json.dumps() turns the Python objects back into JSON text (True → true, None → null), optionally indented.
Default run (43 steps): json.loads() receives 105 characters of text. The scanner starts at char 0 and reads one token at a time. … json.dumps(data, indent=2) turns the Python objects back into JSON text (171 characters): True → true, None → null, and strings get double quotes.
Simplified: Written from scratch to match CPython 3.12's json module (messages and positions checked against it); input is limited to 400 characters and 24 nesting levels, and the access path accepts only ["key"] and [index] subscripts. Python 3.13 reports a trailing comma in an object with a different message.
Loading the simulation…
From Text to Usable Data
A JSON response may begin as ordinary text, but your Python program usually needs a list, dictionary, or primitive value that it can work with. The json.loads() function parses a JSON string and builds a corresponding Python data structure. The original string remains unchanged, so assign the returned Python object to a variable.
Parsing the Outer Structure
json.loads(data) reads the JSON string and builds a new Python object. The outer square brackets in the JSON text indicate a list. Curly braces inside that list indicate dictionary objects. Colons separate keys from values, while commas separate elements. After parsing a JSON string representing two users, the result is a Python list containing two dictionaries.
<class 'str'>
<class 'list'>
2
ChuckThe variable data still refers to the original JSON string. The variable info refers to the new Python object returned by json.loads(). Because the outer JSON value is a list, len(info) counts the two user dictionaries. The expression info[0] selects the first dictionary, and info[0]["name"] selects the value associated with its name key.
Following Nested Access
Reading the First User's Name
Given a parsed value named info that contains a list of user dictionaries, retrieve the name of the first user.
- 1Start with info
The parsed result is a list containing user dictionaries.
- 2Use index 0
info[0] selects the first dictionary in the list.
- 3Use the name key
info[0]["name"] looks up the name field in that dictionary.
The expression info[0]["name"] returns Chuck for the source example.
first_user = info[0]
user_name = first_user["name"]
print(user_name)- 1
first_userreceives the dictionary at index 0. - 2
user_namereceives the value associated with the dictionary key name. - 3The print statement displays Chuck for the source example.
- Select the first dictionary from the list.
- Select the value stored under the name key.
- Display the retrieved value.
Knowing the Expected Shape
Parsing JSON does not tell you which path you intended to follow. You need to know the structure in advance: whether the outer value is a list or dictionary, whether a list index is required, and which keys exist in each dictionary. In the user example, you must know that the result is a list of users, that each user is a dictionary, and that the dictionaries contain keys such as id, x, and name.
Tracing Parsing Problems
When parsing or access produces an unexpected result, inspect the process in layers. First verify that the input is a string containing valid JSON. Next confirm the structure of the parsed result. Finally check that every index and key matches that structure. Printing each layer makes it easier to identify where your expectation and the actual data diverged.
Common mistake Forgetting to import json
What it looks likedata = json.loads(raw_text)Why it failsThe name json has not been made available to the program.
Do this insteadImport the json module before calling json.loads().
Common mistake Passing a non-string object to json.loads()
What it looks likejson.loads(info)Why it failsjson.loads()is used to parse a JSON string, not an already parsed Python object.Do this insteadPass the JSON string to json.loads(), then assign its returned Python object to a separate variable.
Common mistake Using a field that does not exist
What it looks likeinfo[0]["email"]Why it failsThe source structure contains fields such as id, x, and name; accessing an absent field can produce a
KeyError.Do this insteadCheck the documented structure and use the exact key that exists.
Common mistake Skipping the structural trace
What it looks likeTrying several keys and indices without checking the parsed result
Why it failsYou cannot reliably navigate the value if you do not know whether each layer is a list or dictionary.
Do this insteadPrint the type and contents of each relevant layer before changing the access expression.
Practice the Transformation
Suppose data contains a JSON string representing a list of two user dictionaries. Each dictionary has the keys id, x, and name, and the first user's name is Chuck. Write Python statements that parse data, store the returned object in info, count the users, and retrieve the first user's name.
Hints
- Import the json module.
- Assign
json.loads(data)to info. - Use
len(info)to count the outer list elements. - Use info[0]["name"] to reach the first user's name.
What do you think happens?
Before running the access expression, what will info[0]["name"] return when info is the parsed user list from the source example?
Reveal answer
Chuck
The index 0 selects the first dictionary, and the name key selects that dictionary's name value.
Key Takeaways
- 1
json.loads()parses a JSON string and returns a new Python object. - 2The original JSON string is unchanged, so store the returned object in a variable.
- 3JSON arrays become Python lists in the parsed structure, while JSON objects become Python dictionaries.
- 4Navigate lists with indices and dictionaries with keys, following the structure documented for the data.
- 5When debugging, inspect the input, parsed type, length, intermediate values, and final key or index access.
At a glance
json.loads()converts JSON text into a new Python data structure without changing the original string.- Square brackets represent the outer list in the user example, while curly braces represent dictionaries inside that list.
- Nested access follows the parsed shape: info[0] selects the first list element and info[0]["name"] selects its name value.
- You must know the expected structure and field names before navigating parsed JSON effectively.
- A step-by-step trace of types, lengths, intermediate values, keys, and indices helps diagnose parsing and access errors.