NOETRION

Choose a topic

DAY 11 OF 30 · FUNCTIONS AND COLLECTIONS

Sets and relationships

Deduplicate values and compare collections through union, intersection, and difference.

90–120 minutes suggested study timePython 3.12Not yet completed

Today's outcomes

  • Create empty and populated sets correctly.
  • Use set operations for coverage checks.
  • Separate membership from ordering and multiplicity.

Before you start: Complete Day 10 and its practical challenge.

Understand the concept

A set represents membership, not a history of observations

A set contains distinct hashable items. Adding the same item again does not create a second copy. That makes sets useful for deduplication and membership questions, such as which topics were covered at least once. It makes them unsuitable for directly counting how many times each topic was studied.

Set elements have no guaranteed display order and cannot be accessed by position. If a report needs a predictable order, create a sorted list for presentation. The mathematical result can remain a set while its display uses a separate sequence.

Use set() for an empty set. {} creates an empty dictionary. A populated set literal looks like {'lists', 'functions'}. Every member must be hashable, so a mutable list cannot directly be a member. A tuple of appropriate immutable values can be hashable, but a tuple containing a list is not.

Set operations describe relationships

Union combines members from either set. Intersection contains members shared by both. Difference contains members of the first set absent from the second. Symmetric difference contains members found in exactly one of the two. Difference is directional: required minus completed answers a different question from completed minus required.

Subset checks answer whether every member of one set is present in another. A superset check asks the reverse relationship. These relationships are useful for coverage, but they do not establish the quality of the work behind each member. Marking “functions” as completed is not evidence that a learner can write a correct function.

Normalization must happen before deduplication when intended

The strings "Lists", "lists", and " lists " are distinct values. A set will not decide that they refer to the same topic. If the application intentionally ignores surrounding whitespace and case for topic labels, derive a comparison key before building the set.

Do not apply that policy universally to IDs or passwords. Some fields intentionally distinguish case or whitespace. Deduplication is correct only relative to an explicitly chosen equality policy. The original labels may still need to be preserved for display or auditing.

Worked example

required = {"functions", "lists", "dictionaries"}
completed = {"functions", "lists", "regex"}

shared = required & completed
missing = required - completed
extra = completed - required
combined = required | completed

print("Shared:", sorted(shared))
print("Missing:", sorted(missing))
print("Extra:", sorted(extra))
print("All required completed:", required <= completed)

assert shared == {"functions", "lists"}
assert missing == {"dictionaries"}
assert extra == {"regex"}
assert len(combined) == 4
Relationship Operation Result in this fixture
Covered required topics required & completed functions, lists
Required topics still missing required - completed dictionaries
Topics beyond this requirement completed - required regex
All mentioned topics required | completed Four distinct topics

In the last operation cell, the vertical bar is the union operator, not a separator between two independent calculations. The exact printed order is controlled by sorted rather than by set iteration.

Guided practice

  1. Predict: convert ['lists', 'lists', 'functions'] to a set. How many members remain? Explain which information about the original study history was lost.
  2. Modify: add dictionaries to completed and check required <= completed again. The extra regex topic does not prevent a subset check from succeeding.
  3. Reconstruct: compare the users who submitted work with the users expected to submit. Produce missing submissions and unexpected IDs separately. Do not describe their union as the missing set.

Practice remove and discard on a known member and an absent member. remove raises KeyError for an absent member; discard does not. Choose the behavior that matches whether absence is a contract violation or an acceptable no-op.

Daily challenge

Implement topic_coverage(required, studied). Both arguments are lists of strings. For this exercise, surrounding whitespace and case are ignored, and empty normalized labels are excluded. Return two sets: missing required topics and extra studied topics. Preserve the supplied lists.

Required Studied Missing Extra
['Lists', 'Functions'] [' lists ', 'REGEX'] functions regex
['Lists', 'Lists'] ['lists'] empty set empty set
[] ['Regex', ''] empty set regex
['Lists'] [] lists empty set

The normalization rule is suitable for this fictional topic-label list. It is not a general record-identity algorithm. Return actual sets and sort them only when displaying the result.

Reference solution

Compare after attempting the challenge
def normalized_topics(labels):
    result = set()
    for label in labels:
        key = label.strip().casefold()
        if key:
            result.add(key)
    return result

def topic_coverage(required, studied):
    expected = normalized_topics(required)
    observed = normalized_topics(studied)
    return expected - observed, observed - expected

assert topic_coverage(["Lists", "Functions"], [" lists ", "REGEX"]) == ({"functions"}, {"regex"})
assert topic_coverage(["Lists", "Lists"], ["lists"]) == (set(), set())
assert topic_coverage([], ["Regex", ""]) == (set(), {"regex"})
assert topic_coverage(["Lists"], []) == ({"lists"}, set())
print("Topic coverage passed")

The helper makes the equality policy visible and reusable. casefold supports a broader caseless transformation than lower; Day 12 discusses text policy further. This function does not perform compatibility or accent-insensitive normalization.

Debug and explain

A fluctuating printed order is not necessarily a fluctuating mathematical result. Compare sets as sets in a test and sort only for stable presentation. If an empty collection has dictionary methods instead of set methods, inspect whether you wrote {} instead of set().

Explain the direction of each difference operation, the information lost during deduplication, and the policy that makes two topic labels equal here. Give a task where a list is necessary because repeated items are meaningful.

Review and next step

Keep the four coverage cases and a note separating order, multiplicity, and membership. Rebuild the two difference expressions during your next review. Day 12 studies strings directly so your text-preparation decisions become more deliberate.

Sources and verification

Original teaching examples checked with Python 3.12.14. Library behavior reviewed against these primary references on October 3, 2026. Day 26's examples also use Beautiful Soup 4.14.3.

DAILY CHECKPOINT

Check your understanding

Five questions, 20 points each. Pass at 85% or above, which requires all five correct. Feedback explains each answer; revise the lesson and retry when needed.

01. How do you create an empty set?

02. What does A - B contain?

03. What does A & B contain?

04. What information is lost when a list becomes a set?

05. What does required <= completed test?

Review your practical work

Check these statements after running your own challenge. This is your self-review; the website does not execute or assess your Python code.

Pass the knowledge check and finish the practical self-review to save completion.