Chapter 142·Beginner·9 min read
Collections: Lists, Tuples, Dictionaries, and Sets
Python's built-in containers for holding many values — lists for ordered sequences, tuples for fixed ones, dictionaries for key-value lookups, and sets for uniqueness. What each is for, how to use it, and how to choose the right one.
July 27, 2026
Every program so far has juggled values one at a time — a single age, a single name. But real data comes in groups: a list of users, a set of scores, a table of settings. Storing each in its own variable would be madness. Python gives you collections — containers that hold many values at once — and it ships with four built-in kinds, each shaped for a different job. Knowing them, and knowing which to reach for, is a genuine step up in what you can build. They pair perfectly with the loops from last chapter: a collection is exactly the thing a for loop loves to walk through.
Lists: the everyday workhorse
A list is an ordered, changeable collection. It's the one you'll use most. Create one with square brackets:
scores = [88, 92, 79, 95]
names = ["Ada", "Alan", "Grace"]
mixed = [1, "two", 3.0, True] # types can mix, though usually they don'tYou reach an item by its index — its position — and here Python's counting-from-zero shows up again: the first item is index 0.
print(names[0]) # Ada (first)
print(names[1]) # Alan (second)
print(names[-1]) # Grace (negative counts from the end!)That -1 trick — negative indexes count backwards from the end — is a lovely Python convenience for "the last item." Lists are mutable, meaning you can change them after creation: add, replace, and remove items freely.
names.append("Linus") # add to the end
names[0] = "Ada Lovelace" # replace an item
names.remove("Alan") # delete by value
print(len(names)) # len() gives the countappend, remove, len(), and looping with for name in names cover most of daily list work. Lists are your default choice whenever you have an ordered bunch of things that might change.
Tuples: ordered and fixed
A tuple is like a list with one key difference: once created, it cannot be changed — it's immutable. You write it with parentheses instead of square brackets:
point = (3, 4)
rgb = (255, 128, 0)
print(point[0]) # 3 — you read it just like a list
# point[0] = 9 # ERROR — tuples can't be modifiedWhy would you want a collection you can't edit? Because "can't be changed" is often exactly the guarantee you want. Coordinates (x, y) belong together and shouldn't drift apart; a database row is a fixed record. Using a tuple signals "these values are a fixed unit" — to Python, and to whoever reads your code. Tuples are also slightly lighter than lists. A handy relative is tuple unpacking, which splits a tuple straight into variables:
point = (3, 4)
x, y = point # x is 3, y is 4Dictionaries: look up by key
Lists find things by position, but often you want to find them by name. That's a dictionary (dict) — a collection of key–value pairs, exactly like a real dictionary maps a word to its definition. Write it with curly braces and key: value pairs:
user = {
"name": "Ada",
"age": 36,
"is_admin": True,
}Instead of remembering that the age is "at position 1," you just ask for it by key:
print(user["name"]) # Ada
user["age"] = 37 # update a value
user["email"] = "a@x.io" # add a new pair
print(user.keys()) # all the keysDictionaries are one of Python's most important and most-used structures. Any time your data has named fields — a user with a name and age, a product with a price and title, settings with options — a dictionary is almost always the right tool. Looping gives you the pairs:
for key, value in user.items():
print(f"{key}: {value}")Sets: unique things only
The fourth container is the set — an unordered collection that automatically keeps only unique items. Write it with curly braces (but just values, no key: value pairs):
tags = {"python", "beginner", "python", "code"}
print(tags) # e.g. {'code', 'python', 'beginner'} — duplicate gone, order not guaranteedA set's defining feature is that duplicates simply can't exist in it — add the same value twice and it's stored once. That makes sets perfect for two jobs: removing duplicates (turn a messy list into a set and back), and fast membership tests ("is this item in the collection?"), which sets answer very quickly.
seen = set()
seen.add("a")
seen.add("a") # ignored — already there
print("a" in seen) # True — the fast membership check
print(len(seen)) # 1Because they're unordered, sets have no indexing — you don't ask for "item 0" of a set. They're about membership and uniqueness, not position.
Choosing the right one
Here's the whole chapter in one decision table — the mental checklist for picking a container:
| Need | Use | Written with |
|---|---|---|
| An ordered list of things that can change | list | [ ] |
| A fixed group of values that shouldn't change | tuple | ( ) |
| Look values up by a name/key | dict | {key: value} |
| Only unique items / fast "is it in here?" | set | { } |
Reach for a list by default; upgrade to a dict the moment you're looking things up by name; choose a tuple when the data is fixed; and pull out a set when uniqueness is the point. That instinct develops fast with practice.
Where this leaves us
You can now hold data in the shape it naturally takes: ordered and editable (lists), fixed (tuples), labelled (dictionaries), or unique (sets) — and you know how to pick between them. Together with variables, types, and control flow, you can already write programs that store and process real information.
But as programs grow, you'll notice yourself writing the same few lines again and again — the same calculation, the same formatting. There's a better way: bundle a piece of logic under a name and reuse it. That's the idea of functions, and it's one of the most important in all of programming — up next: Functions.