Comprehensions — Advanced
Beyond List Comprehensions
You already know list comprehensions. Python extends the same syntax to two other built-in types — dictionaries and sets — and pairs them with two functions, zip and enumerate, that make comprehensions significantly more powerful.
Dictionary Comprehensions
The syntax mirrors list comprehensions, but uses curly braces and a key: value expression:
{key_expression: value_expression for item in iterable}
Each word becomes a key, its length becomes the value. A dictionary built in one line — no {} initialisation, no loop, no dict[key] = value assignment.
Filtering works exactly as with list comprehensions:
Transforming values while keeping keys:
Inverting a Dictionary
A dictionary comprehension is the cleanest way to swap keys and values:
This works correctly only when values are unique. If two keys share a value, the last one wins — the earlier ones are silently overwritten.
Set Comprehensions
Set comprehensions use curly braces without the colon — producing a set of unique values:
The result is automatically deduplicated. Useful when you need unique values from a sequence but don't need order or indexing.
enumerate — Index and Value Together
When looping over a sequence, you often need both the position and the value. The beginner approach:
for i in range(len(items)):
print(i, items[i])
This works but is considered un-Pythonic. enumerate is the right tool:
enumerate wraps any iterable and yields (index, value) tuples. The unpacking index, city gives you both at once — clean and readable.
You can start counting from any number:
enumerate inside a comprehension:
A dictionary mapping each item to its position — built in one line.
zip — Iterating Two Sequences in Parallel
zip pairs items from two (or more) iterables by position:
zip stops at the shortest iterable — if the lists have different lengths, the extra items in the longer one are silently ignored.
Building a dictionary from two parallel lists is one of zip's most common uses:
zip with a comprehension:
Nested Comprehensions
A comprehension can contain another comprehension — useful for working with two-dimensional data.
Flattening a list of lists:
Read the for clauses left to right, outer to inner: for each row in matrix, for each n in row, take n. The order of for clauses in a nested comprehension matches the order you'd write the nested loops.
Building a 2D structure:
The outer comprehension produces rows. The inner comprehension produces the values in each row. Each row is itself a list.
A Practical Example: Combining Everything
One dictionary comprehension: zip pairs students with scores, sorted ranks them highest first, enumerate adds rank numbers, the if clause filters out failures, and the expression formats each entry. Compact — but each piece does exactly one job.
When a comprehension reaches this level of complexity, consider whether a regular loop with named variables would be clearer. Comprehensions are not always the right choice — readability is always the priority.
What You Have Learned
Dict and set comprehensions, enumerate, and zip extend the comprehension toolkit into genuinely powerful territory.
The key ideas:
{k: v for ...}— dictionary comprehension;{v for ...}— set comprehension- Both support
iffiltering, just like list comprehensions - Inverting a dictionary:
{v: k for k, v in d.items()} enumerate(iterable, start=0)— yields(index, value)pairs; avoids manual index trackingzip(a, b)— pairs items by position; stops at the shortest sequencedict(zip(keys, values))— build a dictionary from two parallel lists- Nested comprehensions: outer-to-inner
forclause order matches nested loop order - Complexity is a warning sign — if it takes effort to read, a loop is clearer
In the next lesson, you'll explore functools — Python's module for higher-order function tools including partial, lru_cache, and reduce.