Concepts / Reading JSON from Files with json.load()

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.

  • Programming
Interactive lab

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

  1. The scanner reads the next token: a brace or bracket, a string in double quotes, a number, true / false / null, or a ',' / ':' delimiter.
  2. '{' starts a Python dict and '[' a list; both are pushed on a parse stack until their closing '}' or ']'.
  3. Inside a dict every key must be a double-quoted string followed by ':' and a value; items are separated by ','.
  4. Anything else stops the parse with JSONDecodeError, reporting the message, line, column and character position.
  5. 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).
  6. 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.

Educational simulation

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.

JSON string[{"id": 1, "name":"Chuck"}]json.loads(data)parse the textPython listouter [ ]Python dictionaryinner { }Chuckname valueinputbuildscontainskey name
What happens to JSON text as json.loads() parses its outer container, nested objects, and values?

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.

python
Output
<class 'str'>
<class 'list'>
2
Chuck

The 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

infolist0first dictionaryuser dictionaryid, x, namenamekeyChuckvalueindex [0]selectskey [name]returns
How do you move through the parsed list and dictionary to retrieve the first user's name?
Worked example

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.

  1. 1
    Start with info

    The parsed result is a list containing user dictionaries.

  2. 2
    Use index 0

    info[0] selects the first dictionary in the list.

  3. 3
    Use the name key

    info[0]["name"] looks up the name field in that dictionary.

Result

The expression info[0]["name"] returns Chuck for the source example.

Code walkthrough
first_user = info[0]
user_name = first_user["name"]
print(user_name)
  1. 1
    first_user receives the dictionary at index 0.
  2. 2
    user_name receives the value associated with the dictionary key name.
  3. 3
    The 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.

Python listuse an index0first elementPython dictionaryuse a keynamefield nameindexed bylooked up by
Why must you identify the container type and required key or index before accessing a parsed value?
JSON stringin memoryjson.loads()string parserJSON filefile sourcejson.load()file readerPython objectparsed structureinputinputreturnsreturns
How does the input source named by each function differ when working with JSON?

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.

python
  • Common mistake

    Forgetting to import json

    What it looks like
    data = json.loads(raw_text)
    Why it fails

    The name json has not been made available to the program.

    Do this instead

    Import the json module before calling json.loads().

  • Common mistake

    Passing a non-string object to json.loads()

    What it looks like
    json.loads(info)
    Why it fails

    json.loads() is used to parse a JSON string, not an already parsed Python object.

    Do this instead

    Pass 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 like
    info[0]["email"]
    Why it fails

    The source structure contains fields such as id, x, and name; accessing an absent field can produce a KeyError.

    Do this instead

    Check the documented structure and use the exact key that exists.

  • Common mistake

    Skipping the structural trace

    What it looks like

    Trying several keys and indices without checking the parsed result

    Why it fails

    You cannot reliably navigate the value if you do not know whether each layer is a list or dictionary.

    Do this instead

    Print the type and contents of each relevant layer before changing the access expression.

Practice the Transformation

EASY

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?

  • The entire list

  • The first user dictionary

  • Chuck

  • The number of users

Reveal answer
Answer:

Chuck

The index 0 selects the first dictionary, and the name key selects that dictionary's name value.

Key Takeaways

  1. 1
    json.loads() parses a JSON string and returns a new Python object.
  2. 2
    The original JSON string is unchanged, so store the returned object in a variable.
  3. 3
    JSON arrays become Python lists in the parsed structure, while JSON objects become Python dictionaries.
  4. 4
    Navigate lists with indices and dictionaries with keys, following the structure documented for the data.
  5. 5
    When 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.

Related concepts

More concepts starting with R