Python from zero to data engineering Lesson 10 / 110

Tuples and sets: choose a collection for the job

Use tuples for fixed groups and sets for uniqueness and membership. Make deliberate tradeoffs between order, duplicates, and memory.

Not every group of values needs to be a list. The cinema wants a seat coordinate, a unique list of visiting customer IDs, and a record of every purchase. Those are three different needs.

You need: lists and dictionaries. By the end: you can explain when to choose a tuple or set and what information a conversion might discard. Allow 25–35 minutes.

Tuples: a fixed group of values

seat = ("C", 7)
row, number = seat

print(row)
print(number)
print(seat[0])

Output:

C
7
C

A tuple is an ordered, immutable sequence. You can retrieve positions, but cannot assign a different value to seat[0]. Unpacking assigns its two values to two names; the number of names must match the number of values in this simple form.

Tuples are useful for small fixed groups whose positions are obvious. A record with many fields is often clearer as a dictionary. ("C",) is a one-item tuple; the comma matters. ("C") is just a string in parentheses.

Immutable does not mean that everything inside is recursively frozen. A tuple can hold a mutable list. We will revisit that distinction when studying shared references.

Sets: uniqueness without positions

visitor_ids = ["C01", "C02", "C01", "C03"]
unique_visitors = set(visitor_ids)

print(len(visitor_ids))
print(len(unique_visitors))
print("C02" in unique_visitors)

Output:

4
3
True

A set holds unique elements and supports membership checks. It has no positional indexing and does not guarantee a useful iteration order. Do not write a test that expects a printed set’s elements to appear in a particular order.

Use set() for an empty set: {} creates an empty dictionary. Like dictionary keys, set elements must be hashable; our strings qualify, but lists and dictionaries do not.

checked_in = set()
checked_in.add("B001")
checked_in.add("B001")
checked_in.add("B002")
checked_in.discard("B002")

print(len(checked_in))

This prints 1. Adding the same value twice has no extra effect. discard() removes a value if present and does nothing if absent. remove() would raise KeyError when the value is absent; choose according to whether absence is expected.

Compare groups directly

booked = {"B001", "B002", "B003"}
checked_in = {"B001", "B003", "B999"}

missing = booked - checked_in
unexpected = checked_in - booked
matched = booked & checked_in

print(sorted(missing))
print(sorted(unexpected))
print(sorted(matched))

Output:

['B002']
['B999']
['B001', 'B003']

- computes a difference; & computes an intersection; | computes a union. These operations create new sets. sorted() produces a sorted list for stable display; it does not change the sets.

This is a small reconciliation task: who booked but did not arrive, and who arrived without a matching booking?

Performance is a tradeoff, not a slogan

Membership in a set is usually roughly constant time on average, whereas a list search may inspect every item. If checking many IDs against the same group, create the set once, outside the loop. Rebuilding it for every check throws away much of the benefit.

Sets also require memory and discard duplicate counts and sequence information. Converting purchase records to a set can destroy the very information needed for revenue totals. “Faster” is not useful if the answer changes.

NeedStarting choice
Keep every booking in orderList
Store a record with named fieldsDictionary
Represent a fixed pair such as row and seatTuple
Check unique IDs or compare groupsSet

These are starting choices, not universal laws. A small list may already be fast enough. Avoid creating multiple representations without a clear use for each.

Your turn: two screenings

Morning visitors are ['C01', 'C02', 'C01']; evening visitors are ['C02', 'C03']. Find the total number of unique visitors and the IDs of people who attended both screenings.

Show one solution
morning = set(["C01", "C02", "C01"])
evening = set(["C02", "C03"])

all_visitors = morning | evening
repeat_visitors = morning & evening

print(len(all_visitors))
print(sorted(repeat_visitors))

The answers are 3 and ['C02']. The repeated C01 entry no longer contributes an extra occurrence. Keep the original data too if occurrence counts matter.

Checkpoint: explain why a set helps with repeated membership checks but is a poor replacement for an ordered purchase history.

Search