Data Structures
Variables hold one value. Data structures hold many. Master Python's four built-in containers — lists, dicts, tuples, and sets — and you can model almost anything.
Lists — Ordered, Changeable
A list is an ordered sequence of items. Items can be any type, and the list can grow or shrink.
fruits = ["apple", "banana", "cherry"]
# Indexing — starts at 0, negatives from end
print(fruits[0]) # apple
print(fruits[-1]) # cherry
print(fruits[1:3]) # ['banana', 'cherry'] (slice)
# Modifying
fruits.append("date") # add to end
fruits.insert(1, "avocado") # insert at index
fruits.remove("banana") # remove by value
popped = fruits.pop() # remove & return last
fruits.sort() # sort in-place
print(fruits)
print(len(fruits)) # length
print("apple" in fruits) # True — membership test
# List comprehension — Pythonic way to build lists
numbers = [1, 2, 3, 4, 5]
squares = [n**2 for n in numbers]
evens = [n for n in numbers if n % 2 == 0]
print(squares) # [1, 4, 9, 16, 25]
print(evens) # [2, 4]
Dictionaries — Key → Value
A dictionary maps unique keys to values. Think of it like a real dictionary: look up a word (key), get the definition (value). Lookups are near-instant regardless of size.
person = {"name": "Alice", "age": 30, "city": "London"}
# Access
print(person["name"]) # Alice
print(person.get("phone", "N/A")) # N/A (safe — no KeyError)
# Modify
person["age"] = 31 # update
person["email"] = "a@mail.com" # add new key
del person["city"] # remove
# Iterate
for key, value in person.items():
print(f" {key}: {value}")
# Keys and values
print(list(person.keys())) # ['name', 'age', 'email']
print(list(person.values())) # ['Alice', 31, 'a@mail.com']
# Dict comprehension
scores = {"Alice": 88, "Bob": 72, "Carol": 95}
passing = {name: s for name, s in scores.items() if s >= 80}
print(passing) # {'Alice': 88, 'Carol': 95}
Tuples — Ordered, Immutable
Tuples are like lists but they can't be changed after creation. Use them for data that should stay fixed: coordinates, RGB colours, database rows.
point = (10, 20)
color = (255, 128, 0) # RGB orange
print(point[0]) # 10
print(point[-1]) # 20
# Unpacking — very common pattern
x, y = point
r, g, b = color
print(f"x={x}, y={y}")
print(f"RGB: {r}, {g}, {b}")
# Functions often return tuples
def min_max(numbers):
return min(numbers), max(numbers)
lo, hi = min_max([3, 1, 4, 1, 5, 9, 2])
print(f"min={lo}, max={hi}") # min=1, max=9
# Tuples are faster than lists for read-only data
# and can be used as dictionary keys (lists can't)
Sets — Unique Items, Fast Lookup
A set stores only unique elements and has no defined order. Two killer use cases: removing duplicates instantly, and ultra-fast membership testing.
# De-duplicate a list instantly
raw = [1, 2, 3, 2, 1, 4, 3]
unique = set(raw)
print(unique) # {1, 2, 3, 4}
# Set operations (like in maths)
python_devs = {"Alice", "Bob", "Carol"}
js_devs = {"Bob", "Dave", "Carol"}
both = python_devs & js_devs # intersection
either = python_devs | js_devs # union
py_only = python_devs - js_devs # difference
exclusive = python_devs ^ js_devs # symmetric diff
print("Both: ", both) # {'Bob', 'Carol'}
print("Either: ", either) # all 4 names
print("Py only: ", py_only) # {'Alice'}
print("Exclusive:", exclusive) # {'Alice', 'Dave'}
Choosing the Right Structure
| Structure | Ordered? | Mutable? | Duplicates? | Best for |
|---|---|---|---|---|
| list | ✅ | ✅ | ✅ | Ordered sequences, queues, stacks |
| dict | ✅* | ✅ | ❌ (keys) | Lookup by key, JSON-like data |
| tuple | ✅ | ❌ | ✅ | Fixed data, function return values |
| set | ❌ | ✅ | ❌ | Unique items, fast membership tests |
* Dicts maintain insertion order since Python 3.7