Lists, Tuples, and Sets
What You'll Learn
How to create and use Python's three basic collection types: lists (ordered, mutable), tuples (ordered, immutable), and sets (unordered, unique values).
Lists
A list holds an ordered, mutable sequence of items. Items can be any type and can repeat.
Creating Lists
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", True, 3.14]
empty = []
nested = [[1, 2], [3, 4]]
Accessing Items
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # apple (first item)
print(fruits[-1]) # cherry (last item)
print(fruits[1:3]) # ['banana', 'cherry'] (slicing)
print(fruits[:2]) # ['apple', 'banana']
print(fruits[::2]) # ['apple', 'cherry'] (every 2nd)
Modifying Lists
fruits = ["apple", "banana", "cherry"]
# Change item
fruits[0] = "mango"
# Add items
fruits.append("grape") # add to end
fruits.insert(1, "kiwi") # insert at index 1
fruits.extend(["pear", "plum"]) # add multiple items
# Remove items
fruits.remove("banana") # remove first occurrence
popped = fruits.pop() # remove and return last item
popped = fruits.pop(0) # remove and return item at index 0
del fruits[0] # delete at index
fruits.clear() # remove all items
Searching and Sorting
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print(len(numbers)) # 8
print(numbers.count(1)) # 2 (how many times 1 appears)
print(numbers.index(5)) # 4 (index of first 5)
print(5 in numbers) # True
print(min(numbers)) # 1
print(max(numbers)) # 9
print(sum(numbers)) # 31
numbers.sort() # sort in place
numbers.sort(reverse=True) # sort descending
sorted_copy = sorted(numbers) # returns new sorted list, leaves original unchanged
numbers.reverse() # reverse in place
List Comprehensions
Build a list from a loop in one line:
# Traditional loop
squares = []
for n in range(10):
squares.append(n ** 2)
# List comprehension (cleaner)
squares = [n ** 2 for n in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# With filter
evens = [n for n in range(20) if n % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# Transform strings
names = ["alice", "bob", "charlie"]
upper = [name.upper() for name in names]
# ['ALICE', 'BOB', 'CHARLIE']
Tuples
A tuple holds an ordered, immutable sequence. Once created, you cannot change it.
# Creating tuples
coordinates = (10.5, 20.3)
rgb = (255, 128, 0)
single = (42,) # single-item tuple — note the trailing comma!
empty = ()
# Parentheses are optional
point = 10, 20 # same as (10, 20)
Why Use Tuples Instead of Lists?
- Immutability: signals that this data shouldn't change
- Performance: tuples are slightly faster than lists
- Dictionary keys: tuples can be used as dict keys; lists cannot
- Unpacking: natural for returning multiple values from a function
# Unpacking — clean and readable
x, y = (10, 20)
lat, lon = (37.7749, -122.4194)
first, *rest = [1, 2, 3, 4, 5]
# first = 1, rest = [2, 3, 4, 5]
# Functions returning multiple values (actually returns a tuple)
def get_min_max(numbers):
return min(numbers), max(numbers)
low, high = get_min_max([3, 1, 4, 1, 5, 9])
print(f"min={low}, max={high}") # min=1, max=9
Tuple Methods
Tuples have only two methods (since they're immutable):
t = (1, 2, 3, 2, 1)
print(t.count(2)) # 2 — how many times 2 appears
print(t.index(3)) # 2 — index of first 3
Sets
A set holds unordered, unique values. Duplicates are automatically removed.
# Creating sets
fruits = {"apple", "banana", "cherry", "apple"} # duplicate removed
print(fruits) # {'apple', 'banana', 'cherry'} (order may vary)
numbers = set([1, 2, 3, 2, 1]) # from a list
print(numbers) # {1, 2, 3}
empty_set = set() # NOT {} — that creates an empty dict!
Set Operations
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
# Union — all items from both
print(a | b) # {1, 2, 3, 4, 5, 6}
print(a.union(b))
# Intersection — items in both
print(a & b) # {3, 4}
print(a.intersection(b))
# Difference — in a but not in b
print(a - b) # {1, 2}
print(a.difference(b))
# Symmetric difference — in one but not both
print(a ^ b) # {1, 2, 5, 6}
Modifying Sets
fruits = {"apple", "banana"}
fruits.add("cherry") # add one item
fruits.update(["mango", "kiwi"]) # add multiple items
fruits.remove("apple") # remove (raises KeyError if missing)
fruits.discard("grape") # remove (no error if missing)
popped = fruits.pop() # remove and return arbitrary item
fruits.clear() # remove all
Fast Membership Testing
Sets are much faster than lists for in checks on large data:
# O(n) — slow for large lists
banned_list = ["spam@evil.com", "bot@fake.com", ...]
if email in banned_list: # scans entire list
# O(1) — instant regardless of size
banned_set = {"spam@evil.com", "bot@fake.com", ...}
if email in banned_set: # hash lookup
Choosing the Right One
| Need | Use |
|---|---|
| Ordered, changeable | list |
| Ordered, fixed (won't change) | tuple |
| Unique values, fast lookup | set |
| Pairs of coordinates or RGB | tuple |
| Deduplicate a list | list(set(items)) |
| Return multiple values | tuple |
# Deduplicate a list (order not preserved)
items = [3, 1, 4, 1, 5, 9, 2, 6, 5]
unique = list(set(items))
# Deduplicate preserving order
seen = set()
unique_ordered = [x for x in items if x not in seen and not seen.add(x)]
Quick Reference
# List
lst = [1, 2, 3]
lst.append(4) # add to end
lst.insert(0, 0) # insert at index
lst.remove(2) # remove value
lst.pop() # remove last
lst.sort() # sort in place
sorted(lst) # new sorted copy
len(lst)
# Tuple
t = (1, 2, 3)
a, b, c = t # unpack
t.count(1)
t.index(2)
# Set
s = {1, 2, 3}
s.add(4)
s.remove(2)
s.discard(99) # no error if missing
a | b a & b a - b a ^ b