DAY 4 - Collections: Lists, Tuples, Dictionaries & Sets
4.1 Lists
A list is an ordered, mutable collection of items. Items can be of any type, and duplicates are allowed.
scores = [85, 92, 78, 95, 88]
names = ["Alice", "Bob", "Charlie"]
mixed = [1, "hello", 3.14, True] # valid but unusual in practiceAccessing items - indexing and slicing
Exactly like strings (because strings are sequences too):
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
print(fruits[0]) # apple
print(fruits[-1]) # elderberry
print(fruits[1:3]) # ['banana', 'cherry']
print(fruits[::-1]) # reversed listModifying lists
Lists are mutable - you can change them after creation:
colours = ["red", "green", "blue"]
colours[1] = "yellow" # replace item
print(colours) # ['red', 'yellow', 'blue']
colours.append("purple") # add to end
colours.insert(1, "orange") # insert at index 1
print(colours) # ['red', 'orange', 'yellow', 'blue', 'purple']Essential list methods
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
numbers.append(7) # add 7 to the end
numbers.remove(1) # remove the FIRST occurrence of 1
popped = numbers.pop() # remove and return the last item
popped_at = numbers.pop(2) # remove and return item at index 2
numbers.sort() # sort in place (ascending)
numbers.sort(reverse=True) # sort descending
print(len(numbers)) # number of items
print(numbers.count(5)) # how many times 5 appears
print(numbers.index(9)) # index of the first occurrence of 9
copy = numbers.copy() # create a shallow copy
numbers.clear() # remove all itemsChecking membership
cities = ["London", "Paris", "Berlin"]
print("London" in cities) # True
print("Tokyo" in cities) # False
print("Tokyo" not in cities) # TrueList comprehensions
List comprehensions are a compact, Pythonic way to create lists. They are used extensively in data work.
Standard loop approach:
squares = []
for n in range(1, 6):
squares.append(n ** 2)
# [1, 4, 9, 16, 25]List comprehension equivalent:
squares = [n ** 2 for n in range(1, 6)]
# [1, 4, 9, 16, 25]With a condition (filter):
even_squares = [n ** 2 for n in range(1, 11) if n % 2 == 0]
# [4, 16, 36, 64, 100]String transformation:
names = [" alice ", "BOB", " Charlie "]
clean_names = [name.strip().title() for name in names]
# ['Alice', 'Bob', 'Charlie']4.2 Tuples
A tuple is an ordered, immutable collection. Once created, it cannot be changed. Use tuples for data that should not be modified - coordinates, RGB values, database records.
coordinates = (51.5074, -0.1278) # London lat/long
rgb_red = (255, 0, 0)
dimensions = (1920, 1080)
print(coordinates[0]) # 51.5074Attempting to modify a tuple raises a TypeError:
coordinates[0] = 48.8566 # TypeError: 'tuple' object does not support item assignmentTuple unpacking
One of the most useful Python features - assigning multiple variables at once:
point = (10, 20, 30)
x, y, z = point
print(x) # 10
print(y) # 20
print(z) # 30# Swap two variables in one line - a Python classic
a, b = 5, 10
a, b = b, a
print(a, b) # 10 54.3 Dictionaries
A dictionary stores data as key-value pairs. Keys must be unique and immutable (typically strings or integers). Dictionaries are unordered in theory, but in Python 3.7+ they maintain insertion order.
student = {
"name": "Jordan Smith",
"age": 28,
"programme": "Data Analytics",
"enrolled": True
}Accessing values
print(student["name"]) # Jordan Smith
print(student.get("age")) # 28
print(student.get("grade", "N/A")) # N/A - default if key doesn't existUse .get() over [] when a key might not exist - [] raises a KeyError, .get() returns None (or your default) gracefully.
Modifying dictionaries
student["age"] = 29 # update existing key
student["cohort"] = "March 2025" # add new key
del student["enrolled"] # delete a key
popped = student.pop("cohort") # remove and return a valueIterating over dictionaries
for key in student:
print(key)
for value in student.values():
print(value)
for key, value in student.items(): # most common pattern
print(f"{key}: {value}")Useful dictionary methods
print(student.keys()) # dict_keys(['name', 'age', 'programme'])
print(student.values()) # dict_values(['Jordan Smith', 29, 'Data Analytics'])
print(student.items()) # dict_items([...])
print("name" in student) # True - checks keys
student.update({"age": 30, "city": "London"}) # merge/update multiple keys4.4 Sets
A set is an unordered collection of unique items. Duplicates are automatically removed. Sets are useful for membership testing and mathematical set operations.
tags = {"python", "data", "analytics", "python", "sql"}
print(tags) # {'python', 'data', 'analytics', 'sql'} - duplicates removedSet operations
skills_a = {"python", "sql", "excel", "tableau"}
skills_b = {"python", "r", "sql", "power_bi"}
print(skills_a | skills_b) # union - all unique skills from both
print(skills_a & skills_b) # intersection - skills in BOTH
print(skills_a - skills_b) # difference - skills in a but NOT in b
print(skills_a ^ skills_b) # symmetric difference - in one but NOT bothRemoving duplicates from a list
A common data-cleaning trick:
data = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique_data = list(set(data))
print(unique_data) # [1, 2, 3, 4, 5] - order not guaranteed4.5 Choosing the Right Collection
| Collection | Ordered | Mutable | Duplicates | Use when |
|---|---|---|---|---|
| list | ✅ | ✅ | ✅ | Ordered, changeable sequence |
| tuple | ✅ | ❌ | ✅ | Fixed data, unpacking, dict keys |
| dict | ✅ (3.7+) | ✅ | Keys: ❌ | Key-value lookup |
| set | ❌ | ✅ | ❌ | Uniqueness, membership tests |
✏️ Day 4 Exercises
Exercise 4.1 - Student List Manager
Create a programme that manages a list of student names. It should:
- Start with a list of 3 names.
- Add a 4th name using
.append(). - Insert a name at position 1 using
.insert(). - Remove one name using
.remove(). - Print the final sorted list and its length.
Hint: .sort() modifies the list in place. If you want a sorted copy without changing the original, use sorted(list).
Exercise 4.2 - Word Frequency Counter
Given the following text, count how many times each word appears and print the results as a dictionary:
text = "the cat sat on the mat the cat sat"Expected output:
{'the': 3, 'cat': 2, 'sat': 2, 'on': 1, 'mat': 1}Hint: use .split() to get a list of words. Then loop through the words. For each word, check if it is already in your dictionary - if it is, increment its count; if not, set it to 1. Alternatively, look up dict.get(key, default).
Exercise 4.3 - Data Cleaning with List Comprehensions
You receive a messy list of city names:
raw_cities = [" london", "PARIS ", "berlin", " MADRID ", "rome "]Use a single list comprehension to produce a clean list where every city name is stripped of whitespace and in Title Case. Expected output:
['London', 'Paris', 'Berlin', 'Madrid', 'Rome']Hint: .strip().title() chained together does both operations at once.
Exercise 4.4 - Challenge: Inventory System
Create a dictionary representing a shop's inventory. Each key is a product name (string), and each value is a dictionary with "price" (float) and "stock" (int).
- Start with at least 4 products.
- Print all items with stock below 5 as a “low stock” warning.
- Apply a 10% discount to all items above £50.
- Print the full updated inventory, formatted neatly.
Hint: iterate with .items() to access both key and value. To modify values while iterating, it is safer to iterate over list(inventory.items()) or update a copy.
📌 Day 4 Summary
| Concept | What you learned |
|---|---|
| Lists | Ordered, mutable sequences with indexing and slicing |
| List methods | .append(), .insert(), .remove(), .pop(), .sort() |
| List comprehensions | Compact way to build and filter lists |
| Tuples | Immutable sequences; tuple unpacking |
| Dictionaries | Key-value stores; .get(), .items(), .update() |
| Sets | Unique collections; union, intersection, difference |
Tomorrow you will write your own functions - the single most important skill for writing clean, reusable, professional code.