Skip to main content

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 = ["[email protected]", "[email protected]", ...]
if email in banned_list: # scans entire list

# O(1) — instant regardless of size
banned_set = {"[email protected]", "[email protected]", ...}
if email in banned_set: # hash lookup

Choosing the Right One

NeedUse
Ordered, changeablelist
Ordered, fixed (won't change)tuple
Unique values, fast lookupset
Pairs of coordinates or RGBtuple
Deduplicate a listlist(set(items))
Return multiple valuestuple
# 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

What's Next

Lesson 2: Dictionaries and Nested Records