← Home

097. Set Comprehensions

Build sets concisely to collect unique transformed values

097. Set Comprehensions

Rohan collects snapshots every 5 seconds for an hour. Each snapshot has a list of running processes. He wants to know: which unique process names appeared across ALL snapshots?

Without set comprehensions:

seen = set()
for snap in snapshots:
    for proc in snap["processes"]:
        seen.add(proc["name"].lower())

With a set comprehension:

seen = {
    proc["name"].lower()
    for snap in snapshots
    for proc in snap["processes"]
}

One expression. No .add() calls. Duplicates are discarded automatically.

He also needs the unique set of PID owners (the user each process runs as):

owners = {proc["username"] for proc in snapshot["processes"] if proc["username"]}

And the set of distinct RSS sizes rounded to the nearest 100 MB (useful for bucketing):

buckets = {(proc["rss_mb"] // 100) * 100 for proc in snapshot["processes"]}

Set vs list comprehension: Use {...} for uniqueness, [...] when order matters or duplicates are meaningful. A set lookup x in s is O(1); a list lookup is O(n). For 10,000 processes, that’s the difference between microseconds and milliseconds.

πŸ’‘ Fun fact: Python sets are implemented as hash tables β€” the same data structure used in dictionaries. The set type was added in Python 2.4 (2004), and set comprehension syntax {x for x in ...} was introduced in Python 2.7 / 3.0. Before that, you had to write set(x for x in ...).

⚠️ Watch out: The most common beginner mistake is confusing {} (empty dict) with set() (empty set). Writing s = {} creates an empty dict, not a set. To create an empty set, always write set().

πŸ€” Think about it: If sets are unordered and discard duplicates, what happens when you convert a list with duplicates to a set and then back to a list? Can you ever rely on the resulting order?

Learning objectives

  • Create sets with set comprehensions using curly braces
  • Add filter conditions to set comprehensions
  • Understand that set comprehensions automatically deduplicate
  • Choose set vs list based on whether uniqueness or order is needed

Key concepts

  • set comprehension
  • deduplication
  • unique values
  • hashable

Try it

Concept detail

Set comprehension syntax: {expression for variable in iterable [if condition]}

Examples: {word.lower() for word in words} β€” unique lowercased words {x for x in items if x > 0} β€” unique positive values {email.split(β€œ@”)[1] for email in emails} β€” unique email domains

The result is always a set β€” duplicates are automatically discarded. Unlike list comprehensions, set comprehensions have no guaranteed order.

When to use a set vs list: Set β†’ you need uniqueness, fast membership testing (O(1)) List β†’ you need order, duplicates are meaningful, or you need indexing

{x for x in items} is equivalent to set(x for x in items) but the comprehension form is preferred for readability.

Cannot store unhashable types in a set: {[1, 2], [3, 4]} # TypeError β€” lists are not hashable {(1, 2), (3, 4)} # OK β€” tuples are hashable

Nested set comprehension (flat): {ch for word in words for ch in word if ch.isalpha()} β€” all unique letters across all words

Solution

def unique_domains(emails):
    return {email.split("@")[1] for email in emails}

def unique_lengths(words):
    return {len(word) for word in words}

def vowels_in(text):
    return {ch for ch in text.lower() if ch in "aeiou"}

Tests

def test_unique_domains():
    emails = ["[email protected]", "[email protected]", "[email protected]"]
    result = unique_domains(emails)
    assert result == {"gmail.com", "yahoo.com"}

def test_unique_domains_one():
    emails = ["[email protected]", "[email protected]"]
    assert unique_domains(emails) == {"same.org"}

def test_unique_lengths():
    result = unique_lengths(["cat", "dog", "elephant", "ox"])
    assert result == {3, 8, 2}

def test_vowels_in():
    result = vowels_in("Hello World")
    assert result == {"e", "o"}

def test_vowels_empty():
    result = vowels_in("rhythm")
    assert result == set()

Resources