Academy
ProgrammingPython AdvancedComprehensions — Advanced

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 if filtering, 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 tracking
  • zip(a, b) — pairs items by position; stops at the shortest sequence
  • dict(zip(keys, values)) — build a dictionary from two parallel lists
  • Nested comprehensions: outer-to-inner for clause 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.