datarekha
Python Easy Asked at AmazonAsked at GoogleAsked at Meta

How do list, dict, and set comprehensions work in Python, and when should you avoid them?

The short answer

Comprehensions are syntactic sugar for building a new collection by iterating over an iterable and optionally filtering elements. They are faster than equivalent for-loops because the iteration runs at the C level inside the interpreter. Avoid them when the expression is too complex to read at a glance — a plain loop with descriptive variable names is preferable.

How to think about it

What the interviewer wants to hear

Beyond “it’s a shorter for loop”, a strong answer covers all three variants (list, dict, set), explains the speed win, mentions generator expressions as the memory-efficient cousin, and knows when not to use them.

Syntax and variants

The general form is [expression for item in iterable if condition]. The brackets change depending on the type you want:

# List comprehension — square brackets
squares = [x**2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]

# Dict comprehension — curly braces with a colon
word_lengths = {word: len(word) for word in ["apple", "fig", "banana"]}
# {'apple': 5, 'fig': 3, 'banana': 6}

# Set comprehension — curly braces, no colon (deduplicates automatically)
domains = {email.split("@")[1] for email in ["a@x.com", "b@x.com", "c@y.com"]}
# {'x.com', 'y.com'}

# Generator expression — parentheses — lazy, O(1) memory
total = sum(x**2 for x in range(1_000_000))

Why they are faster than plain loops

A list comprehension uses a dedicated LIST_APPEND bytecode that runs at the C level. A plain for loop calling result.append(x) has to look up the append attribute on every iteration. The comprehension skips that lookup, giving a 20–50% speedup for typical workloads.

Interactive playground — all three comprehension types

Nested comprehension — read order matches loop order

# Flatten a 2-D list
flat = [val for row in matrix for val in row]

# This reads exactly like the nested loop:
for row in matrix:
    for val in row:
        flat.append(val)

When to use a plain loop instead

If the expression needs more than a quick glance to understand, reach for a loop:

# Too dense — hard to debug or extend later
result = [transform(x) for x in data if predicate(x) if secondary(x)]

# Clearer as a loop
result = []
for x in data:
    if predicate(x) and secondary(x):
        result.append(transform(x))
Learn it properly Comprehensions

Keep practising

All Python questions

Explore further

Skip to content