PythonBeginner 13 min Lesson 5 of 30

Day 5 — Tuples and Sets

Tuples for fixed groups of values, sets for uniqueness and fast membership checks. Learn the trade-offs and when each beats a list.

Python · Lesson 5 of 30
0/30 done(0%)

What is it? #

A tuple is like a list that cannot be changed after it is created. You write it with round brackets: point = (12, 40). Because it is fixed, a tuple signals intent — "these values belong together and will not change".

A set is an unordered collection with no duplicates. You write it with curly braces: tags = {"python", "web"}. Adding something that is already there does nothing. Sets also answer "is this in here?" almost instantly, no matter how big they get.

That speed difference is the practical reason to care. Checking x in some_list walks the list item by item. Checking x in some_set jumps straight to the answer using a hash, so it stays fast with a million items.

Sets do not keep order and cannot hold unhashable things like lists. Tuples keep order and can be used as dictionary keys precisely because they cannot change.

Think of it like this #

A tuple is a printed boarding pass: name, seat, gate, all fixed together. You would not scribble a new seat number onto it — you get a new pass.

A set is a guest list at a door. You only care whether someone is on it, and writing the same name twice makes no difference. Nobody asks what position they occupy on the list.

Simple example #

You are handling article tags. The same tag may arrive several times and you only want one of each. You also need to check "does this article have the python tag?" thousands of times while rendering a page. Separately, each article has a fixed (latitude, longitude) pair that should never be edited by accident.

Code #

PYTHON
# Tuple — fixed group of values
location = (28.6139, 77.2090)
lat, lon = location               # unpacking
print(lat, lon)

# location[0] = 0.0              # TypeError: tuples cannot be changed

# Set — unique values, fast lookups
raw_tags = ["python", "web", "python", "api", "web"]
tags = set(raw_tags)
print(tags)                       # {'api', 'python', 'web'} — order not guaranteed
print(len(tags))                  # 3
print("python" in tags)           # True

tags.add("backend")
tags.discard("web")               # no error if missing
print(sorted(tags))               # ['api', 'backend', 'python']

# Set maths
current = {"python", "api", "sql"}
required = {"python", "docker", "sql"}
print(current & required)         # {'python', 'sql'}  — in both
print(required - current)         # {'docker'}         — missing
print(current | required)         # everything, once each

How it works #

location = (28.6139, 77.2090) creates a tuple. lat, lon = location unpacks it — Python matches the values on the right to the names on the left in order. This is the same mechanism that lets a function return two values.

The commented line shows the defining property: assigning into a tuple raises TypeError. That is a feature. If a value must not change, a tuple makes accidental changes impossible rather than merely discouraged.

set(raw_tags) builds a set from the list and drops the duplicates in one step. Printing it shows no particular order — never rely on set ordering, and call sorted() when you need a stable display order.

.add() inserts one item, and .discard() removes one without complaining if it was not there (.remove() raises an error in that case).

The last three lines are set algebra, and they replace loops you would otherwise write by hand. & gives the overlap, - gives what the first set is missing relative to the second, and | merges both. "Which required skills does this candidate not have?" is one operator, not a nested loop.

Real-world use #

Sets are the standard fix for deduplication: unique visitor IDs, unique tags, unique email addresses from a messy import. They are also the standard fix for slow membership checks — turning a list of allowed values into a set before a loop is a common one-line performance win.

Set operations map neatly onto permission checks: the roles a user has intersected with the roles an endpoint requires. If the intersection is empty, refuse the request.

Tuples appear whenever a function needs to return more than one thing, and as dictionary keys for coordinate-like data — grid[(row, col)] works because the tuple is hashable, while a list key would be rejected.

Common mistakes #

  • Writing (5) and expecting a tuple. That is just the number 5 in brackets — a one-item tuple needs a trailing comma: (5,).
  • Relying on set order. Sets have no meaningful order; sort them when the output is shown to a person.
  • Trying to put a list inside a set. Lists are mutable and therefore unhashable — convert to a tuple first.
  • Using a list for membership checks in a hot loop when a set would make it instant.
  • Assuming a tuple is deeply immutable. If a tuple holds a list, that inner list can still be modified.

Practice #

You have visited = ["/home", "/pricing", "/home", "/docs", "/pricing"]. Print the number of unique pages, print them in alphabetical order, and then use set operations to find which of {"/home", "/blog", "/docs"} were never visited.

Quick quiz

  1. 1. What is the main difference between a list and a tuple?

  2. 2. What does `set([1, 2, 2, 3])` give you?

  3. 3. Why is `x in my_set` usually faster than `x in my_list`?

  4. 4. What does `{1, 2, 3} & {2, 3, 4}` return?

  5. 5. How do you write a tuple with exactly one item?

Summary

  • Tuples are fixed groups of values — good for coordinates, records and multiple return values.
  • Sets hold unique items and answer membership questions quickly.
  • Set operators `&`, `-` and `|` replace loops for overlap, difference and merge.
  • Sets are unordered; sort them before showing them to a person.
  • A one-item tuple needs a trailing comma, and mutable things cannot go inside a set.