First exams 2027 · HL only

B4.1.5 · Fundamentals of ADTs

Sets

A set answers exactly one question about membership: is this here or not? It never answers "how many times," and it never answers "in what order."

HL only Typically 1–2 marks per part · AO2/AO3 Command term: construct, apply

Explainer

Think of a mailing list that must send exactly one email per address, no matter how many times someone signs up. Storing addresses in a set makes duplicates impossible by construction: adding the same address twice just leaves the set exactly as it was.

Df

A set is an unordered collection where each value can appear at most once. There's no index, no position, no "first element", only membership: a value is either in the set or it isn't. The core operation is the membership testA yes/no check: "is this value in the collection?" Nothing about position, count, or order, just present or not., asking whether a given value is present.

This is B4's own guiding question in miniature, which ADT is most appropriate for a given situation: a list and a set store data the same basic way, but the situation decides which one actually fits.

List

Real example: a class register, seat by seat. Order matters (seat 1 is always seat 1), and two students could share a name, duplicates are fine.

Advantage

  • Keeps order and position (you can always ask for "the 3rd item")

Disadvantage

  • Checking membership is slow (no shortcut: check every item, one by one, until found or the list ends)
Set

Real example: the mailing list above. Position never matters, only "have I already got this address?", and duplicates are impossible by construction.

Advantage

  • Duplicates are impossible (the add operation itself refuses to store the same value twice)

Disadvantage

  • No position or order (there is no "3rd item" in a set; you can never ask for one)
?

Two different things this statement asks for. The syllabus asks you to construct a set as an ADT from first principles (a wrapper around a list, not Python's built-in set), covering four operations specifically: membership (is this value here?), add, remove, and subset/superset (is every element of one set also in the other?). It also expects you to use Python's real set operators (in, &, |, <=) when a question is written in that form. Both come up, and they're not the same skill.

?

What does "subset" mean? Set A is a subset of set B if every single element of A is also in B (B is then A's superset). In the diagram below, the overlap, {Beth, Chen}, is a subset of both circles: everyone in the overlap is, by definition, also in each original set. That's true of every intersection, not just this example.

Worked example

Two sets, and what's shared between them

subscribers holds everyone signed up. notified holds everyone already emailed. Click a name to see which set (or sets) it belongs to, or use the operator buttons below.

Click a name, or try an operator.

subscribers notified

Click a name or an operator to see the result.

Click through: what add() and remove() actually do

Before reading a whole class definition, watch a set starting empty and five calls run on it in order, one at a time.

start

An empty set. Nothing has run yet.

Step 1 of 6

Watch steps 4 and 6 especially: adding a value that's already there changes nothing (that's what makes it a set, not a list), and removing a value that was never there is safe, not an error.

# Constructing all four required set operations from first principles
class MySet:
    def __init__(self):
        self.items = []

    def contains(self, value):        # membership
        return value in self.items

    def add(self, value):
        if not self.contains(value):   # the check that enforces uniqueness
            self.items.append(value)

    def remove(self, value):
        if self.contains(value):
            self.items.remove(value)

    def is_subset_of(self, other):
        for value in self.items:
            if not other.contains(value):
                return False          # found one element NOT in other: not a subset
        return True              # every element checked and found: it is a subset

# Using Python's real set type and operators, a separate skill
subscribers = {"Amir", "Beth", "Chen"}
notified = {"Beth", "Chen", "Dara"}

print("Beth" in subscribers)          # membership test
print(subscribers & notified)            # intersection
print(subscribers | notified)            # union
print({"Beth", "Chen"} <= subscribers)  # subset test
// Constructing all four required set operations from first principles
class MySet {
    List<String> items = new ArrayList<>();

    boolean contains(String value) {        // membership
        return items.contains(value);
    }

    void add(String value) {
        if (!contains(value)) {   // the check that enforces uniqueness
            items.add(value);
        }
    }

    void remove(String value) {
        if (contains(value)) {
            items.remove(value);
        }
    }

    boolean isSubsetOf(MySet other) {
        for (String value : items) {
            if (!other.contains(value)) {
                return false;          // found one element NOT in other: not a subset
            }
        }
        return true;              // every element checked and found: it is a subset
    }
}

// Java's real Set type, a separate skill from building one by hand
Set<String> subscribers = new HashSet<>(Arrays.asList("Amir", "Beth", "Chen"));
Set<String> notified = new HashSet<>(Arrays.asList("Beth", "Chen", "Dara"));

System.out.println(subscribers.contains("Beth"));       // membership test
System.out.println(subscribers.containsAll(notified));  // superset test

The guide's current generator only produces Python. Java is shown here as a reference for schools teaching that track. is_subset_of checks every element of one set against the other, one at a time; the built-in <= operator does the same check under the hood.

Tracing is_subset_of: a true case and a false case

The fourth required operation, traced the same way add and remove were above. subscribers is still {"Amir", "Beth", "Chen"}.

{"Beth","Chen"}.is_subset_of(subscribers)
  check "Beth""Beth" in subscribers → True, keep going
  check "Chen""Chen" in subscribers → True, keep going
  every element checkedTrue
{"Dara"}.is_subset_of(subscribers)
  check "Dara""Dara" in subscribers → False
  stop immediatelyFalse

The false case doesn't need to check every element, one missing value is enough to return False straight away. The true case is the only one that has to check all the way to the end, since it can't rule anything out until it's checked everything.

Check your understanding

Given the sets above, what does print(subscribers & notified) output?

Common mistake

Markers reported this pattern for B4.1.5

RecurringMarkers reported candidates losing marks on "describe this operation" questions by writing only what the operation is for (its purpose) instead of what it actually does, step by step. The two are easy to conflate, but a mark scheme almost always wants the mechanism, not the motivation.

✕

What a weak answer looks like: "The add method is used to put a new value into the set." States the purpose, not the mechanism, no mention of the uniqueness check.

✓

What it should say: "The add method checks whether the value already exists in the set. If it does not, the value is appended; if it does, nothing changes." Describes the actual steps.

Revision questions

Past-paper style. Write an answer, then reveal the marking points and mark yourself.

Question 1 · 1 mark

[1]State the output of print(12 in {5, 12, 40}).

Question 2 · 2 marks

[2]Outline how a set can be used to ensure that only one confirmation email is sent to each customer, even if they submit the form twice.

Question 3 · 4 marks

[4]Construct a method is_subset_of(self, other) for a set implemented as a wrapper around a Python list, without using the built-in set type or its <= operator.

Flashcards

Active recall for this statement's key terms.