← Back to Course Index
Lesson 11 of 13

Sets, Comprehensions & Built-ins

~20 min · set, dict/set comprehensions, zip, sorted, any/all, walrus operator

Ref
Primary Source
Official Docs — Built-in Functions

The complete list of Python's built-in functions. You'll reach for this constantly. Also see the sets section of the data structures tutorial.

1 — Sets

A set is an unordered collection of unique values. Think of it as a dict with only keys, no values. JavaScript has Set too — Python's is more powerful with native operators.

JavaScript
const s = new Set([1, 2, 3, 2, 1]);
s.size;        // 3
s.has(2);      // true
s.add(4);
s.delete(1);

// No native set operations in JS
const union = new Set([...a, ...b]);
const inter = new Set([...a].filter(x => b.has(x)));
const diff  = new Set([...a].filter(x => !b.has(x)));
Python
s = {1, 2, 3, 2, 1}   # {1, 2, 3} — duplicates removed
len(s)         # 3
2 in s         # True
s.add(4)
s.discard(1)   # remove if present (no error if missing)
s.remove(1)    # remove — KeyError if missing

a = {1, 2, 3}
b = {2, 3, 4}
a | b           # union:        {1, 2, 3, 4}
a & b           # intersection: {2, 3}
a - b           # difference:   {1}
a ^ b           # symmetric diff: {1, 4}
a.issubset(b)   # False
a.issuperset(b) # False

Common set patterns

# Deduplicate a list (order not preserved)
unique = list(set([1, 2, 2, 3, 3, 3]))   # [1, 2, 3]

# Membership test — O(1) vs list's O(n)
VALID_ROLES = {"admin", "editor", "viewer"}
if user.role in VALID_ROLES:   # fast hash lookup
    allow()

# Find duplicates
def find_duplicates(items):
    seen = set()
    dupes = set()
    for item in items:
        if item in seen:
            dupes.add(item)
        seen.add(item)
    return dupes

find_duplicates([1, 2, 2, 3, 4, 3])   # {2, 3}

# frozenset — immutable set (can be used as dict key)
ALLOWED = frozenset({"GET", "POST", "PUT", "DELETE"})
⚠ Empty set gotcha

{} creates an empty dict, not a set. To create an empty set: set().

2 — All Comprehension Types

Lesson 1 covered list comprehensions. Python has four forms:

# List comprehension   → [...]
squares     = [x**2 for x in range(10)]
even_sq     = [x**2 for x in range(10) if x % 2 == 0]

# Dict comprehension   → {...: ...}
word_lens   = {word: len(word) for word in ["hi", "hello", "hey"]}
# {"hi": 2, "hello": 5, "hey": 3}

inverted    = {v: k for k, v in {"a": 1, "b": 2}.items()}
# {1: "a", 2: "b"}

# Set comprehension    → {...}
unique_lens = {len(word) for word in ["hi", "hello", "hey"]}
# {2, 5, 3}

# Generator expression → (...)  — lazy, no memory cost
total       = sum(x**2 for x in range(1_000_000))  # never builds the list

Nested comprehensions

# Flatten a 2D matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat   = [n for row in matrix for n in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Read: "n, for each row in matrix, for each n in that row"

# Transpose
transposed = [[row[i] for row in matrix] for i in range(3)]

# Conditional dict build
data   = {"a": 1, "b": None, "c": 3, "d": None}
clean  = {k: v for k, v in data.items() if v is not None}
# {"a": 1, "c": 3}

3 — Essential Built-in Functions

These are used in almost every Python codebase. Some have JS equivalents; some don't.

zip — pair up iterables

JavaScript — no native zip
const names = ["Alice", "Bob"];
const scores = [95, 87];
// Manual zip
const paired = names.map((n, i) => [n, scores[i]]);
// [["Alice", 95], ["Bob", 87]]
Python — zip built-in
names  = ["Alice", "Bob", "Carol"]
scores = [95, 87, 91]

for name, score in zip(names, scores):
    print(f"{name}: {score}")

# Build a dict from two lists
d = dict(zip(names, scores))
# {"Alice": 95, "Bob": 87, "Carol": 91}

# Unzip (transpose)
pairs = [("Alice", 95), ("Bob", 87)]
names, scores = zip(*pairs)

sorted & sort — with key=

# sorted() — returns new list (works on any iterable)
nums = [3, 1, 4, 1, 5, 9]
sorted(nums)               # [1, 1, 3, 4, 5, 9]
sorted(nums, reverse=True) # [9, 5, 4, 3, 1, 1]

# key= is the killer feature
words = ["banana", "fig", "apple", "cherry"]
sorted(words, key=len)         # ["fig", "apple", "banana", "cherry"]
sorted(words, key=str.lower)   # case-insensitive sort

# Sort complex objects
users = [{"name": "Bob", "age": 30}, {"name": "Alice", "age": 25}]
sorted(users, key=lambda u: u["age"])  # sort by age
sorted(users, key=lambda u: (u["age"], u["name"]))  # multi-key sort

# .sort() — sorts in place (list only, returns None)
nums.sort()
nums.sort(key=lambda x: -x)   # descending

enumerate — index + value together

# Instead of: for i in range(len(items))
items = ["a", "b", "c"]

for i, item in enumerate(items):
    print(i, item)   # 0 a, 1 b, 2 c

for i, item in enumerate(items, start=1):
    print(i, item)   # 1 a, 2 b, 3 c

# Build numbered dict
numbered = {i: item for i, item in enumerate(items)}
# {0: "a", 1: "b", 2: "c"}

any & all — short-circuit tests

# any() — True if at least one element is truthy (like Array.some())
any([False, False, True])   # True
any(x > 0 for x in [-1, -2, 3])   # True — stops at 3

# all() — True if every element is truthy (like Array.every())
all([True, True, True])    # True
all(x > 0 for x in [1, 2, -1])   # False — stops at -1

# Real-world uses
has_admin    = any(u["role"] == "admin" for u in users)
all_verified = all(u["verified"] for u in users)
no_errors    = all(r.ok for r in responses)

map & filter — use sparingly

# map() — lazy transform (prefer list comprehensions)
doubled = list(map(lambda x: x * 2, [1, 2, 3]))

# Useful with existing functions (cleaner than lambdas)
strings = ["1", "2", "3"]
numbers = list(map(int, strings))   # [1, 2, 3]
upper   = list(map(str.upper, ["a", "b"]))  # ["A", "B"]

# filter() — lazy filter (prefer comprehensions)
evens = list(filter(lambda x: x % 2 == 0, range(10)))

min, max, sum — with key=

# Basic
min(3, 1, 4)          # 1
max([3, 1, 4])        # 4
sum([1, 2, 3])        # 6
sum([1, 2, 3], 10)    # 16  ← start value

# With key= (same pattern as sorted)
users = [{"name": "Bob", "age": 30}, {"name": "Alice", "age": 25}]
youngest = min(users, key=lambda u: u["age"])  # {"name": "Alice", "age": 25}

# sum with generator — memory efficient
total = sum(item["price"] for item in cart)

4 — The Walrus Operator (:=)

Python 3.8+ assignment expression — assign and use a value in one expression. Comes up often in while loops and comprehensions.

JavaScript
// Assignment in condition — always worked in JS
let line;
while ((line = readLine()) !== null) {
  process(line);
}

// Common pattern
const match = text.match(/\d+/);
if (match) {
  console.log(match[0]);
}
Python — walrus operator :=
# Read until empty line
while line := input("Enter: "):
    process(line)

# Avoid calling the same function twice
import re
if m := re.search(r"\d+", text):
    print(m.group())   # m is already bound

# In comprehensions — reuse computed value
results = [
    cleaned
    for raw in data
    if (cleaned := raw.strip())   # skip empty after strip
]

5 — Other Frequently Used Built-ins

# isinstance / issubclass
isinstance(42, int)          # True
isinstance(42, (int, float)) # True — checks against tuple of types
issubclass(bool, int)        # True — bool is a subclass of int

# abs, round, pow, divmod
abs(-5)          # 5
round(3.14159, 2)   # 3.14
pow(2, 10)          # 1024  (same as 2**10)
pow(2, 10, 1000)    # 24    (modular exponentiation: 2^10 % 1000)
divmod(17, 5)       # (3, 2) — (quotient, remainder) as tuple

# range
range(5)         # 0,1,2,3,4
range(2, 10, 2)  # 2,4,6,8  (start, stop, step)
range(10, 0, -1) # 10,9,...,1  (countdown)
list(reversed(range(5)))  # [4,3,2,1,0]

# type, id, dir
type(42)         # 
type(42) is int  # True
id(obj)          # memory address (like object identity)
dir(obj)         # list all attributes and methods

# vars, getattr, setattr, hasattr
vars(obj)                    # obj.__dict__
getattr(obj, "name", "default")  # safe attribute access
setattr(obj, "name", "Alice")
hasattr(obj, "name")         # True if attribute exists

# open (covered in Lesson 5) | input | print
name = input("Enter your name: ")
print(f"Hello, {name}!", end="\n", file=sys.stderr)

🧠 Quiz

1. How do you create an empty set in Python?

2. What does {k: v for k, v in d.items() if v} do?

3. all(x > 0 for x in [1, 2, -1, 4]) returns:

4. What is the cleanest way to build {"Alice": 95, "Bob": 87} from two separate lists?

5. What does the walrus operator := do?

0/5

Questions answered correctly.