Legends ofPythos
Claim your name
Working with Data

Nested data structures

Lesson 6 of 14

Watch the lesson1:18 · with Torsten
Real-world data is rarely flat. A single list of numbers or a simple dictionary usually isn't enough to describe the world around you.

Think about your phone's contact book. Each person has a name, a number, and maybe an email address. That looks like one small dict per person:
alice = {'name': 'Alice', 'phone': '555-0123'}
But you have many contacts. So the natural shape is a list of dictionaries.

List of dicts

contacts = [
    {'name': 'Alice',  'phone': '555-0123'},
    {'name': 'Bob',    'phone': '555-0456'},
    {'name': 'Chloe',  'phone': '555-0789'}
]

print(contacts[0]['name'])   # Alice
A list where every element is its own dict.
contacts is a list. contacts[0] grabs the first dict inside it, and then ['name'] pulls out one field from that dict.

This pattern of indexing into an index and a key in sequence is called chained indexing. You can chain as many levels deep as you need.

Looping over nested data

contacts = [
    {'name': 'Alice',  'phone': '555-0123'},
    {'name': 'Bob',    'phone': '555-0456'},
    {'name': 'Chloe',  'phone': '555-0789'}
]

for person in contacts:
    print(person['name'], '->', person['phone'])

# Alice -> 555-0123
# Bob -> 555-0456
# Chloe -> 555-0789
Pull one field out of every dict in the list.
The loop variable person is just a dict on each pass. You treat it like any other dict: index into its keys with [...].

This shape — list of dicts, one per record — shows up everywhere: rows in a database table, items from an API response, log entries.

Dicts whose values are lists

teams = {
    'red':   ['Alice', 'Bob'],
    'blue':  ['Chloe', 'Dana'],
    'green': []
}

print(teams['red'])        # ['Alice', 'Bob']
print(len(teams['blue']))  # 2
The other common shape: a dict mapping keys to small collections.
Here the top level is a dict, and each value happens to be a list. You reach into it with teams[key], then treat that result like any other list — index it, loop over it, measure its length.

The two shapes (list-of-dicts vs. dict-with-list-values) cover most real data you'll meet at this level.

Your turn

0 of 3 solved

Exercise 1

+30 XP
Given the list of dicts below, write code that prints only the names of every contact who has a phone number starting with '555'. Print one name per line. Do not print anything else.
contacts = [
    {'name': 'Alice',  'phone': '555-0123'},
    {'name': 'Bob',    'phone': '444-9876'},
    {'name': 'Chloe',  'phone': '555-0789'},
    {'name': 'Dana',   'phone': '222-1357'}
]

Run your code to check it against the tests.

Exercise 2

+30 XP
Below is a dict mapping team names to lists of member names. Add up how many members there are across all teams, store that number in a variable called total, and print it (a single integer, no extra text). Do not print anything else.
teams = {
    'red':   ['Alice', 'Bob'],
    'blue':  ['Chloe', 'Dana', 'Evan'],
    'green': []
}

Run your code to check it against the tests.

Exercise 3

+30 XP
Below is a dict mapping user names to lists of their recent scores. Write code that prints the name (only the name) of every user whose most recent score — the last element in their list — is 10 or higher.

Print one name per line, in the order users appear when you iterate over scores.keys(). Do not print anything else.
scores = {
    'alice': [3, 7, 10],
    'bob':   [9, 4, 8],
    'chloe': [5, 6]
}

Run your code to check it against the tests.