Lesson 9 - Dictionaries & Tuples
Learning Objective
Store and look up labeled data with dictionaries, group fixed, related values with tuples, and know when to use each.
Introduction
Lists work well when data is simply a sequence of values.
However, many real-world datasets contain labeled information:
- A student’s name, age, and scores
- A robot joint’s minimum and maximum angle
- A product’s name, price, and inventory count
For these situations, Python provides dictionaries, which store data as key-value pairs.
Python also provides tuples, which are similar to lists but cannot be modified after they are created. Tuples are ideal for representing fixed structures such as coordinates, colors, or hardware limits.
In this lesson you’ll learn:
- How to create and use dictionaries
- How to safely retrieve values
- How to add and update dictionary entries
- How to iterate through key-value pairs
- How tuples differ from lists
- How to unpack tuple values
Dictionaries
A dictionary stores data using keys and values.
student = {
"name": "Aditi",
"age": 24,
"scores": [82, 91, 76]
}Each key maps to a value:
| Key | Value |
|---|---|
"name" | "Aditi" |
"age" | 24 |
"scores" | [82, 91, 76] |
Accessing Values
Retrieve values using their keys.
print(student["name"])Output:
AditiSafe Lookups with get()
Accessing a missing key directly raises an error:
student["email"]Output:
KeyErrorA safer alternative is:
student.get("email", "not provided")Output:
not providedThis returns the default value instead of crashing.
Adding and Updating Values
Add a new key:
student["email"] = "aditi@example.com"Update an existing key:
student["age"] = 25Iterating Through a Dictionary
Use .items() to access keys and values together.
for key, value in student.items():
print(f"{key}: {value}")Output:
name: Aditi
age: 25
scores: [82, 91, 76]
email: aditi@example.comTuples
A tuple is an ordered collection of values.
point = (3, 4)Like lists, tuples support:
- Indexing
- Slicing
- Iteration
Unlike lists, tuples cannot be modified.
Tuple Unpacking
A tuple can be unpacked into separate variables.
point = (3, 4)
x, y = pointEquivalent to:
x = 3
y = 4Lists vs Tuples
Mutable (can be changed)
items = [1, 2, 3]
items.append(4)Best for collections that grow or change.
ListImmutable (cannot be changed)
point = (3, 4)Best for fixed structures and constants.
TupleCode
# dicts_and_tuples.py
student = {
"name": "Aditi",
"age": 24,
"scores": [82, 91, 76],
}
print(student["name"])
print(student.get("email", "not provided"))
student["email"] = "aditi@example.com"
student["age"] = 25
print(student)
for key, value in student.items():
print(f"{key}: {value}")
# Tuples: fixed, ordered, immutable groupings
point = (3, 4)
x, y = point
print(f"x={x}, y={y}")
# point[0] = 10 # would raise TypeError
coordinates = [(0, 0), (3, 4), (-1, 2)]
for px, py in coordinates:
print(f"Point: ({px}, {py})")Expected Output
Click to see expected output
Aditi
not provided
{'name': 'Aditi', 'age': 25, 'scores': [82, 91, 76], 'email': 'aditi@example.com'}
name: Aditi
age: 25
scores: [82, 91, 76]
email: aditi@example.com
x=3, y=4
Point: (0, 0)
Point: (3, 4)
Point: (-1, 2)Tuple Immutability
Attempting to modify a tuple raises an error.
point = (3, 4)
point[0] = 10Output:
TypeErrorThis protection makes tuples useful when values should never change.
Dictionaries Containing Tuples
Dictionaries and tuples are often used together.
Example:
limits = {
"shoulder": (-90, 90),
"elbow": (0, 135)
}Accessing a tuple:
shoulder_min, shoulder_max = limits["shoulder"]Results:
shoulder_min = -90
shoulder_max = 90🔧 Under the Hood
Why use a tuple instead of a list for something like a coordinate?
Dictionary keys must be hashable, which means they must be immutable.
For example:
point = (3, 4)can be used as a dictionary key:
locations = {
(3, 4): "Home"
}But:
[3, 4]cannot.
This is because lists can change, while tuples cannot.
The immutability of tuples also makes them a good choice for fixed structures:
- Coordinates
- RGB colors
- Min/max ranges
- Hardware limits
For example:
point = (3, 4)represents a coordinate that should not suddenly become:
(10, 4)by accident.
Why get() Is Useful
This code:
student["email"]fails if the key doesn’t exist.
Using:
student.get("email", "not provided")returns the default value instead.
This makes programs more robust and avoids unnecessary crashes.
Dictionary Order
Since Python 3.7, dictionaries preserve insertion order.
That means:
for key, value in student.items():iterates through keys in the order they were originally added.
Student Challenge
Challenge 1
Given a sentence string (e.g. "the quick brown fox jumps over the lazy dog the fox runs"), write a program that counts how many times each word appears and stores the word counts in a dictionary.
- Use
.split()to break the sentence into a list of words. - Use an empty dictionary
frequency = {}to track counts. - Loop over each word and update its count using
.get(word, 0) + 1so you can handle unseen words without key errors. - Finally, use
.items()to print out each word along with its frequency.
Hint
This expression:
frequency.get(word, 0)returns:
0the first time a word is encountered.
That means:
frequency[word] = frequency.get(word, 0) + 1works without needing:
if word in frequencychecks.
Click to see solution
# word_frequency.py
sentence = "the quick brown fox jumps over the lazy dog the fox runs"
words = sentence.split()
frequency = {}
for word in words:
frequency[word] = frequency.get(word, 0) + 1
for word, count in frequency.items():
print(f"{word}: {count}")Challenge 2
Look up the real angle limits for your BonicBot’s arm, then move through a dictionary of named poses.
Extend the POSES dictionary with a new pose:
"point"and confirm the robot moves through it without changing any other code.
Full servo method details are available in the Python SDK reference.
Hint
This syntax:
**anglesunpacks a dictionary into keyword arguments.
For example:
{
"shoulder": 90,
"elbow": 30
}becomes:
shoulder=90,
elbow=30automatically.
Click to see solution
# challenge_arm_poses.py
from bonicbot_bridge import BonicBot
POSES = {
"rest": {"shoulder": 0, "elbow": 0},
"wave": {"shoulder": 90, "elbow": 30},
"reach": {"shoulder": 45, "elbow": 40},
"point": {"shoulder": 60, "elbow": 20},
}
with BonicBot(host='192.168.0.188') as bot:
limits = bot.get_servo_limits()
shoulder_min, shoulder_max = limits["left_shoulder"]
print(
f"Left shoulder range: "
f"{shoulder_min}° to {shoulder_max}°"
)
for pose_name, angles in POSES.items():
print(f"Moving to '{pose_name}' pose...")
bot.move_left_arm(
shoulder=angles["shoulder"],
elbow=angles["elbow"]
)
bot.move_left_arm(**POSES["rest"])Reflection Question
get_servo_limits()returns a dictionary where each value is a(min, max)tuple rather than a list[min, max]. Given that a joint’s hardware limits never change while your program runs, why is a tuple the more honest choice here than a list?
By the end of this lesson, you should be able to store labeled data in dictionaries, safely retrieve values using get(), iterate through key-value pairs, create and unpack tuples, and choose appropriately between lists and tuples based on whether data should be mutable or fixed.