Preparing your learning space...
100% through Collections tutorials
Collections are data types that hold multiple values. Python has four built-in collection types: lists, tuples, sets, and dictionaries. Each serves a different purpose, and knowing when to use which one is a core skill.
A collection is a data structure that stores multiple items in a single variable. Instead of creating separate variables for every piece of data, you group related items together.
Without collections, you'd write code like this:
fruit1 = "apple"
fruit2 = "banana"
fruit3 = "cherry"
With a collection, you write this:
fruits = ["apple", "banana", "cherry"]
Collections make your code shorter, easier to manage, and let you loop over data instead of writing the same operation for every variable. Python's four collection types each have different strengths — the rest of this tutorial covers when and why to use each one.
A list is an ordered, changeable collection that can hold items of any type.
fruits = ["apple", "banana", "cherry"]
mixed = [1, "hello", 3.14, True]
empty = []
Lists use square brackets [] and keep their order. You can have duplicates, add items, remove items, and change existing items.
# Empty list
items = []
# With initial values
colors = ["red", "green", "blue"]
# Using list() constructor
numbers = list((1, 2, 3, 4))
Use the index inside square brackets. Indexes start at 0.
colors = ["red", "green", "blue"]
print(colors[0]) # red
print(colors[-1]) # blue (last item)
print(colors[1:3]) # ["green", "blue"] (slicing)
colors = ["red", "green", "blue"]
colors.append("yellow") # add to end
colors.insert(1, "orange") # add at position 1
colors.remove("green") # remove by value
popped = colors.pop() # remove and return last item
del colors[0] # remove by index
colors.clear() # remove everything
if "red" in colors:
print("Found it!")
Most of the real work you do with lists involves looping, transforming, and searching.
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# With index
for i, fruit in enumerate(fruits):
print(i, fruit)
This is Python's most elegant feature for lists — a compact way to create one list from another.
# Old way
squares = []
for x in range(10):
squares.append(x ** 2)
# List comprehension
squares = [x ** 2 for x in range(10)]
# With condition
evens = [x for x in range(20) if x % 2 == 0]
# Transform while filtering
names = ["Alice", "Bob", "Charlie"]
short_names = [name.upper() for name in names if len(name) > 3]
numbers = [3, 1, 4, 1, 5, 9]
numbers.sort() # in-place, ascending
numbers.sort(reverse=True) # in-place, descending
sorted_list = sorted(numbers) # returns new sorted list
The difference between sort() and sorted(): sort() changes the original list, sorted() returns a new one.
nums = [1, 2, 3, 4, 5]
len(nums) # 5 — number of items
sum(nums) # 15
min(nums) # 1
max(nums) # 5
# Join list items into a string
words = ["hello", "world"]
sentence = " ".join(words) # "hello world"
# Copy a list
copy1 = nums.copy()
copy2 = list(nums)
copy3 = nums[:] # slice shorthand
Important: copy2 = nums does not copy — both variables point to the same list. Use .copy(), list(), or slicing [:].
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(matrix[1][2]) # 6
A tuple is an ordered, immutable collection — once created, you cannot change it.
point = (10, 20)
rgb = (255, 128, 0)
single = (5,) # comma required for single-item tuple
Tuples use parentheses (). Because they cannot be changed, they are:
# A point on a grid should never change
point = (10, 20)
# Months don't change
months = ("Jan", "Feb", "Mar", "Apr")
# Function returning multiple values
def min_max(numbers):
return min(numbers), max(numbers)
result = min_max([3, 1, 4, 1, 5])
print(result) # (1, 5)
low, high = result # unpacking
point = (10, 20, 30)
len(point) # 3
point[0] # 10
point.count(10) # count occurrences
point.index(20) # find position
# Check membership
if 10 in point:
print("yes")
# Concatenate
combined = (1, 2) + (3, 4) # (1, 2, 3, 4)
A set is an unordered collection of unique items.
fruits = {"apple", "banana", "cherry"}
numbers = {1, 2, 3, 2, 1} # {1, 2, 3} — duplicates removed
empty = set() # not {} — that's an empty dict
Sets use curly braces {} but without key-value pairs. They automatically remove duplicates and have no defined order.
students = {"Alice", "Bob", "Charlie"}
teachers = {"Bob", "Diana", "Eve"}
# Membership — very fast even on large sets
if "Alice" in students:
print("present")
# Add and remove
students.add("Frank")
students.remove("Bob") # error if not found
students.discard("Bob") # no error if not found
# Set theory
print(students | teachers) # union — all unique names
print(students & teachers) # intersection — names in both
print(students - teachers) # difference — names only in students
print(students ^ teachers) # symmetric difference — names in one or the other
emails = ["a@x.com", "b@x.com", "a@x.com", "c@x.com"]
unique_emails = list(set(emails))
# ["a@x.com", "b@x.com", "c@x.com"]
Sets lose their order, so if you need to preserve order while removing duplicates, loop and track seen items:
seen = set()
unique_ordered = []
for email in emails:
if email not in seen:
unique_ordered.append(email)
seen.add(email)
A dictionary stores key-value pairs. It's like a real dictionary — you look up a word (key) and get its definition (value).
student = {
"name": "Alice",
"age": 22,
"grade": "A"
}
empty = {}
config = dict() # also creates empty dict
Keys must be immutable (strings, numbers, tuples) and unique. Values can be anything.
student = {"name": "Alice", "age": 22}
print(student["name"]) # Alice
print(student.get("name")) # Alice
print(student.get("major", "N/A")) # "N/A" — safe default
student["age"] = 23 # update
student["major"] = "CS" # add new key
del student["age"] # remove a key
major = student.pop("major") # remove and return the value
Use .get() instead of [] when a key might be missing — it avoids errors.
user = {"name": "Alice", "age": 22, "city": "NYC"}
# Keys
for key in user:
print(key)
# Values
for value in user.values():
print(value)
# Both
for key, value in user.items():
print(f"{key}: {value}")
if "name" in user:
print("name exists")
This checks keys, not values. For values, use if "Alice" in user.values().
Counting items:
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
print(counts) # {"apple": 3, "banana": 2, "cherry": 1}
Grouping items:
students = [("Alice", "A"), ("Bob", "B"), ("Charlie", "A")]
by_grade = {}
for name, grade in students:
if grade not in by_grade:
by_grade[grade] = []
by_grade[grade].append(name)
print(by_grade) # {"A": ["Alice", "Charlie"], "B": ["Bob"]}
Dictionary comprehension:
squares = {x: x ** 2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Real-world data is rarely flat. Dictionaries handle nesting naturally.
users = {
"alice": {"age": 22, "city": "NYC", "skills": ["Python", "SQL"]},
"bob": {"age": 25, "city": "LA", "skills": ["Java", "C++"]}
}
print(users["alice"]["city"]) # NYC
print(users["bob"]["skills"][0]) # Java
Save your progress and earn XP for completing tutorials.
Keep learning
Technology
Python
Lesson group
Collections
Progress
100% complete