blog / guides

python JSON parsing: 8 examples you can try

by Luke published 9 min read

the short answer

Parsing JSON in Python takes one line, json.loads(text), and gives you ordinary dictionaries and lists. The real work is what comes next: digging into nested data, looping over records, filtering, counting, and turning the result back into JSON with json.dumps. The eight examples below show each step with code you can run, plus the type surprises to watch for.

Parsing JSON in Python takes one line: json.loads(text) turns JSON text into ordinary dictionaries and lists. What you do next is where the real work is. This page is a set of eight small examples to run, each one a task you will meet with real data: digging into a reply, adding things up, filtering, counting, tidying and saving.

If JSON is new to you, start with our guide to parsing JSON in Python, which explains what JSON is, how its types map onto Python’s and how to handle broken input. Everything below builds on it.

Before you start: explore the data

Real JSON rarely arrives with instructions. Before writing any loops, spend a minute finding out what you have been given. Three questions answer most of it: what type is the outer value, what keys or how many items does it have, and what does one record look like?

try it · python
import json

text = '{"shop": "Corner Café", "items": [{"name": "Tea", "price": 2.5}, {"name": "Scone", "price": 3}]}'
data = json.loads(text)
print(type(data))
print(list(data.keys()))
print(len(data["items"]))
print(data["items"][0])
<class 'dict'>
['shop', 'items']
2
{'name': 'Tea', 'price': 2.5}

Now you know the outside is a dictionary, the records live under items, and each record has a name and a price. Notice that one price is 2.5 and the other is plain 3. JSON does not care, and Python turns them into a float and an int, so format them when you print them. With this map in your head, every example below is a short step.

1. Reading a nested reply

Weather services, maps and shops send back JSON with objects inside lists inside objects. Work from the outside in:

try it · python
import json

reply = """{
  "town": "Leeds",
  "daily": [
    {"day": "Fri", "max": 9, "min": 3, "rain": 0.6},
    {"day": "Sat", "max": 11, "min": 5, "rain": 0.1}
  ]
}"""

data = json.loads(reply)
for d in data["daily"]:
    print(f"{data['town']} {d['day']}: {d['min']} to {d['max']}°C, rain {d['rain']:.0%}")
Leeds Fri: 3 to 9°C, rain 60%
Leeds Sat: 5 to 11°C, rain 10%

data is a dictionary, data["daily"] is a list, and each d is a dictionary again. When you are lost in nested data, print one level at a time, such as print(data["daily"][0]), until you can see the path to the value you want.

2. Totals and averages

A JSON array of records turns into a list of dictionaries, which a loop or sum can add up:

try it · python
import json

orders = json.loads('[{"id": 101, "total": 24.5}, {"id": 102, "total": 8.0}, {"id": 103, "total": 13.25}]')
takings = sum(order["total"] for order in orders)
print("Orders:", len(orders))
print(f"Takings: £{takings:.2f}")
print(f"Average: £{takings / len(orders):.2f}")
Orders: 3
Takings: £45.75
Average: £15.25

sum(order["total"] for order in orders) reads as “add up the total of every order”. It is shorter than a loop with a running total, and does the same thing.

Real data is not always complete. If some orders might arrive without a total, order.get("total", 0) counts them as zero instead of stopping with a KeyError. Decide on purpose whether a missing value should count as zero or be reported, because the two give different answers.

3. Keeping only some records

try it · python
import json

products = json.loads("""[
  {"name": "Kettle", "price": 25, "in_stock": true},
  {"name": "Toaster", "price": 32, "in_stock": false},
  {"name": "Mug", "price": 6, "in_stock": true}
]""")

available = [p["name"] for p in products if p["in_stock"]]
print(available)
cheap = [p["name"] for p in products if p["in_stock"] and p["price"] < 10]
print(cheap)
['Kettle', 'Mug']
['Mug']

JSON’s true and false arrive as Python’s True and False, so if p["in_stock"] works directly. The square brackets build a new list of only the names that pass the test.

4. Counting with a dictionary

try it · python
import json

posts = json.loads('[{"tags": ["python", "json"]}, {"tags": ["python"]}, {"tags": ["sql", "json"]}]')
counts = {}
for post in posts:
    for tag in post["tags"]:
        counts[tag] = counts.get(tag, 0) + 1
print(counts)
{'python': 2, 'json': 2, 'sql': 1}

counts.get(tag, 0) gives the count so far, or 0 the first time a tag appears. This pattern, a loop inside a loop with a tally, turns up whenever data has lists inside records.

5. Pretty printing

try it · python
import json

settings = {"theme": "dark", "volume": 7, "shortcuts": ["save", "undo"]}
print(json.dumps(settings))
print(json.dumps(settings, indent=2, sort_keys=True))
{"theme": "dark", "volume": 7, "shortcuts": ["save", "undo"]}
{
  "shortcuts": [
    "save",
    "undo"
  ],
  "theme": "dark",
  "volume": 7
}

indent=2 puts each value on its own line, two spaces in per level. sort_keys=True puts the keys in alphabetical order, which makes two versions of the same data easy to compare. Leave both out when the JSON is only for other programs, since the extra spaces make files bigger without helping a computer read them.

6. Change it and turn it back into JSON

try it · python
import json

text = '{"theme": "light", "volume": 7}'
settings = json.loads(text)
settings["theme"] = "dark"
settings["volume"] += 1
print(json.dumps(settings))
{"theme": "dark", "volume": 8}

Parse, change, dump: that is how a program updates a settings file or sends back an edited record. To save the result on your own computer, open the file for writing and let json.dump write straight into it:

with open("settings.json", "w", encoding="utf-8") as f:
    json.dump(settings, f, indent=2)

The with line closes the file for you when the block ends, even if something goes wrong. Setting the encoding means symbols like £ are saved the same way on every computer.

7. Keeping symbols readable

try it · python
import json

item = {"name": "Crème brûlée", "price": "£5"}
print(json.dumps(item))
print(json.dumps(item, ensure_ascii=False))
{"name": "Cr\u00e8me br\u00fbl\u00e9e", "price": "\u00a35"}
{"name": "Crème brûlée", "price": "£5"}

Both lines are valid JSON and mean the same thing. By default Python writes accented letters and symbols as codes, which is safe for any system. ensure_ascii=False keeps them as they are, which is much easier for people to read.

8. The type surprises

JSON has fewer types than Python, so a few things change on the way through. Keys become text, and tuples become lists:

try it · python
import json

winners = {1: "Ava", 2: "Ben"}
back = json.loads(json.dumps(winners))
print(back)
print(back.get(1), back.get("1"))
print(json.loads(json.dumps((3, 4))))
{'1': 'Ava', '2': 'Ben'}
None Ava
[3, 4]

After the round trip, back.get(1) finds nothing, because the key is now the text "1". Convert keys back with int if you need numbers.

Dates are not JSON at all, so Python refuses to write one. Turn it into text first:

try it · python
import json
from datetime import date

event = {"name": "Quiz night", "on": date(2026, 11, 20)}
try:
    print(json.dumps(event))
except TypeError as error:
    print("Error:", error)

event["on"] = event["on"].isoformat()
print(json.dumps(event))
Error: Object of type date is not JSON serializable
{"name": "Quiz night", "on": "2026-11-20"}

Sets give the same error. Turn them into a list with list() first. One more trap: Python will write float("nan") as NaN, which strict JSON readers reject. Pass allow_nan=False if your JSON is going to another system, and Python will stop with a ValueError instead.

Common mistakes

Forgetting to parse

try it · python
reply = '{"town": "Leeds"}'
print(reply["town"])
  File "<exec>", line 2, in <module>
TypeError: string indices must be integers, not 'str'

The reply is still text. Text can only be indexed by position, so Python complains about the key. Pass it through json.loads first.

Looping over a dictionary and getting only keys

A for loop over a dictionary gives its keys, not its values. Use for day, temp in data.items(): when you want both.

Guessing the key names

Keys are case-sensitive and must match exactly, so data["Town"] raises a KeyError when the JSON says "town". Print the parsed data, or data.keys(), and copy the names you see.

Mixing up loads and dumps

loads turns text into Python. dumps turns Python into text. The s stands for string, and the versions without it work with files.

A short exercise

This JSON holds a class’s quiz scores. Print the top scorer and the average score to one decimal place:

text = '[{"name": "Ava", "score": 18}, {"name": "Ben", "score": 15}, {"name": "Cal", "score": 20}]'

Your output should be Top: Cal with 20 and then Average: 17.7. Try it in the playground from the button at the bottom of the page, choosing Python.

One possible answer

try it · python
import json

text = '[{"name": "Ava", "score": 18}, {"name": "Ben", "score": 15}, {"name": "Cal", "score": 20}]'
pupils = json.loads(text)
best = max(pupils, key=lambda p: p["score"])
average = sum(p["score"] for p in pupils) / len(pupils)
print(f"Top: {best['name']} with {best['score']}")
print(f"Average: {average:.1f}")
Top: Cal with 20
Average: 17.7

max with key= compares the pupils by their scores but hands back the whole record, so you get the name as well as the number.

Your next step

Nearly every program that talks to the web reads and writes JSON. Gwecode’s Python Level 2 teaches it alongside dictionaries, files and fetching data from the web, and its level check has you build a budget tracker that saves its own data. Every lesson is free and runs in your browser. Create a free account to keep your progress, and try the JSON lesson below.

practise this · python · lessonJSON: data as textstart the lesson

questions

How do I get a value out of nested JSON in Python?

Parse it with json.loads, then chain the keys and positions, such as data["daily"][0]["max"]. Work from the outside in, one level at a time.

How do I loop over a JSON array in Python?

After json.loads, a JSON array is a Python list, so a for loop goes through it. Each item is usually a dictionary, so read its fields by key.

Why did my number keys turn into strings?

JSON only allows text as object keys. json.dumps turns the key 1 into "1", and json.loads leaves it as "1", so a round trip changes your keys.

How do I keep the £ sign readable in JSON?

Pass ensure_ascii=False to json.dumps. Without it, Python writes characters outside plain English text as codes, so £ becomes \u00a3.

How do I save a date in JSON?

JSON has no date type. Turn the date into text first, usually with .isoformat(), which gives a value like 2026-11-20 that is easy to turn back into a date later.

keep going.