🔷 Introduction

As you move beyond beginner-level Python, one of the first skills you need to strengthen is the ability to work with complex data structures. In real-world applications—APIs, databases, machine learning pipelines, web scrapers—data often arrives in nested or mixed forms: lists inside dictionaries, dictionaries inside lists, queues for processing, sets for filtering unique values, and more.

This lesson explores intermediate data structures that will help you manage, organize, and manipulate data efficiently as your programs grow in complexity.

🟩 1. Nested Lists

Nested lists (lists inside lists) represent matrices, grids, tables, or grouped information.

✅ Example: 2D list (matrix)

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(matrix[1][2])  # 6

💡 When to use nested lists

🟩 2. Dictionaries of Lists & Lists of Dictionaries

Dictionaries of Lists

Useful when storing multiple values under categories:

students = {
    "names": ["Sara", "Adam", "Lina"],
    "scores": [85, 92, 78]
}

print(students["names"][1])  # Adam

Lists of Dictionaries

This is one of the most common data structures in APIs and databases:

users = [
    {"id": 1, "name": "Ali"},
    {"id": 2, "name": "Yassine"},
    {"id": 3, "name": "Salma"}
]

print(users[2]["name"])  # Salma

💡 When it matters

🟩 3. Tuples vs Namedtuples

Tuples are immutable ordered collections:

point = (10, 20)

Namedtuples add structure + readability:

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(10, 20)

print(p.x, p.y)

💡 Why use namedtuples?

🟩 4. Sets & Set Operations

A set is an unordered collection of unique items.

numbers = {1, 2, 3, 3, 4}
print(numbers)  # {1, 2, 3, 4}

Set operations

a = {1, 2, 3}
b = {3, 4, 5}

print(a | b)  # union
print(a & b)  # intersection
print(a - b)  # difference

💡 Where sets are used

🟩 5. Stacks & Queues

(Using list and deque)

A. Stack (LIFO – Last In First Out)

stack = []
stack.append("A")
stack.append("B")
stack.append("C")

print(stack.pop())  # C

Used in:

B. Queue (FIFO – First In First Out)

Using collections.deque (fast):

from collections import deque

queue = deque(["A", "B", "C"])

queue.append("D")
print(queue.popleft())  # A

Used in:

🟧 6. Exercise Block (with hidden solutions)

Exercise 1

Create a 3×3 matrix and print its diagonal.

Exercise 2

You have the following list of dictionaries. Print the name of the oldest person.

people = [
   {"name": "Sara", "age": 22},
   {"name": "Adam", "age": 30},
   {"name": "Lina", "age": 27}
]

Exercise 3

Remove duplicates from a list using a set.

🟦 Conclusion

This lesson introduced the intermediate data structures that professionals use daily to manage complex information. Mastering them will significantly boost your ability to build real-world Python applications, especially when dealing with APIs, files, or databases