Skip to content

Tuples & Sets

Two more collection types — each with a specific job.

Tuples — ordered, immutable lists

Use () instead of [].

point = (3, 4)
colors = ("red", "green", "blue")
person = ("Alice", 25, "Mumbai")
empty = ()
single = (5,)        # NOTE: trailing comma is required for one-item tuple

print(point, colors, person, empty, single)

When to use a tuple

  • Group related values that shouldn't change: coordinates, dates, RGB colors.
  • Function returns multiple values (it's actually returning a tuple).
  • Dictionary keys — tuples can be keys (lists can't).
  • A tiny bit faster than lists for read-only data.

Tuple operations

t = (10, 20, 30, 40, 50)

print(t[0])       # 10 — indexing works
print(t[-1])      # 50
print(t[1:4])     # (20, 30, 40) — slicing works
print(len(t))     # 5
print(20 in t)    # True

# These FAIL because tuples are immutable:
# t[0] = 99       # TypeError
# t.append(60)    # AttributeError

Unpacking

The Pythonic way to destructure a tuple:

point = (3, 4)
x, y = point
print(x, y)              # 3 4

# Swap with unpacking
a, b = 1, 2
a, b = b, a
print(a, b)              # 2 1

# Star unpacking — collect the rest
first, *middle, last = (1, 2, 3, 4, 5)
print(first, middle, last)    # 1 [2, 3, 4] 5

Named tuples — readable tuples

When unpacking gets confusing, give fields names:

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y)         # 3 4
print(p)                 # Point(x=3, y=4)

# Still supports tuple operations
print(p[0], p[1])        # 3 4
x, y = p
print(x, y)              # 3 4

Sets — unique, unordered collections

Use {} for set literals (but {} alone is an empty dict — use set() for an empty set).

fruits = {"apple", "banana", "cherry"}
empty_set = set()
mixed = {1, "hello", 3.14, True}

print(fruits, empty_set, mixed)

Two key properties of sets

  1. No duplicates — duplicates get silently dropped.
  2. No order — items have no index.
# Duplicates removed automatically
nums = {1, 2, 2, 3, 3, 3, 4}
print(nums)              # {1, 2, 3, 4}

# Remove duplicates from a list
items = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique = list(set(items))
print(unique)            # [1, 2, 3, 4, 5] (order not guaranteed)

Adding / removing

s = {1, 2, 3}

s.add(4)
print(s)                  # {1, 2, 3, 4}

s.update([5, 6, 7])       # add many
print(s)

s.remove(7)               # raises KeyError if not present
s.discard(99)             # silent if not present
print(s)

popped = s.pop()          # remove and return ARBITRARY element
print("popped:", popped)

Membership check — sets are FAST

big_set = set(range(1_000_000))

# `x in set` is O(1) — instant, no matter the size
print(999_999 in big_set)    # True

# Compare to list: `x in list` is O(n) — slow on big lists

When checking many in queries, use a set, not a list.

Set operations — union, intersection, difference

These are the math operations from set theory:

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a | b)         # union          {1, 2, 3, 4, 5, 6}
print(a & b)         # intersection   {3, 4}
print(a - b)         # difference     {1, 2}  (in a but not in b)
print(a ^ b)         # symmetric diff {1, 2, 5, 6}  (in either but not both)

# Subset / superset
print({1, 2}.issubset(a))         # True
print(a.issuperset({1, 2}))       # True

Frozensets — immutable sets

fs = frozenset([1, 2, 3])
print(fs)
# fs.add(4)         # AttributeError — frozensets can't be modified

# Can be used as dict keys / inside another set
nested = {fs, frozenset([4, 5, 6])}
print(nested)

Quick comparison

Property list tuple set
Syntax [1,2] (1,2) {1,2}
Ordered? yes yes no
Indexed? yes yes no
Mutable? yes no yes (but frozenset no)
Duplicates? yes yes no
Fast membership? slow O(n) slow O(n) fast O(1)
Use when order matters grouping constants uniqueness or fast lookup

Mini-project — find common friends

alice_friends = {"Bob", "Charlie", "Diana", "Eve"}
bob_friends   = {"Alice", "Charlie", "Frank", "Diana"}

mutual = alice_friends & bob_friends
print("Mutual friends:", mutual)

alice_only = alice_friends - bob_friends
print("Alice-only friends:", alice_only)

all_friends = alice_friends | bob_friends
print("Everyone:", all_friends)

Practice

What does this print?

Expected: 4

nums = [1, 2, 2, 3, 3, 3, 4]
print(len(set(nums)))

Make this print {1, 2, 5, 6} (symmetric difference)

Expected: {1, 2, 5, 6}

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b)        # bug: this gives intersection, not symmetric diff

Quiz — Quick check

What you remember

Q1. Which is NOT a property of a set?

  • Unordered
  • No duplicates
  • Fast membership check
  • Items are accessed by index

Why: Sets have no positional order, so my_set[0] is a TypeError. If you need indexing, convert to a list first or use a list.

Q2. What does (5,) represent?

  • A syntax error
  • A list of one element
  • A tuple with one element
  • The number 5 wrapped in parens

Why: The trailing comma is required for a one-element tuple. (5) is just the number 5 in parentheses — Python treats the parens as grouping.

Q3. Checking x in big_set vs x in big_list — which is faster?

  • in big_set is dramatically faster (O(1) vs O(n))
  • in big_list is faster
  • Same speed
  • Depends on whether x is present

Why: Sets are hash tables — checking membership takes constant time regardless of size. Lists must scan front-to-back. For 1 million items, set is ~1,000,000× faster.

Common doubts

Tuple or list — which should I use?

Tuple when the size and content are fixed (coordinates, RGB color, a date tuple). List when items will be added, removed, or mutated. Tuples are also slightly faster to create and can be used as dict keys; lists can't.

Why is {} an empty dict, not an empty set?

Historical: dicts came first. {} is reserved for empty dict. For an empty set you must write set(). {1, 2, 3} is a set; {"key": "value"} is a dict — the contents decide.

Are sets unordered? Even in Python 3.7+?

Yes, sets remain unordered. Python 3.7+ made dicts preserve insertion order, but sets do not. If you need a "set" that keeps order, the workaround is a dict with None values: dict.fromkeys(items).

What's next

Dictionaries