Skip to main content
Python Basics2026-07-29 · 8 min read

Python List Comprehensions Explained: When to Use Them and When Not To (2026)

List comprehensions are one of Python's most misunderstood features. Beginners avoid them because "they look complicated". Intermediates over-use them until every third line is a nested one-liner nobody can read. This tutorial fixes both mistakes.

We'll cover: the exact three-part shape every list comprehension follows, benchmarks vs for / map / filter, the four patterns you should recognise on sight, and a hard rule for when to stop using comprehensions and reach for a plain loop instead.

The shape: [ what | source | filter ]

Every list comprehension is three parts, in this order:

▶ PYTHONeditable · runs in your browser

Reading it out loud: "give me `expression` for each `item` in `iterable`, but only when `condition` is true."

Start with the equivalent for loop, then collapse it:

▶ PYTHONeditable · runs in your browser

Same result — [0, 4, 16, 36, 64]. The comprehension is one line, allocates the list up front (no append calls), and Python's bytecode compiler emits LIST_APPEND — a fast path that skips the attribute lookup on .append.

Benchmark: comprehension vs for-loop vs map+filter

Building a list of squared even numbers from 0 to 100,000:

| Method | Time (µs) | Relative |

|---|---|---|

| for + .append | 4,800 | 1.9× baseline |

| list(map(..., filter(...))) | 3,200 | 1.3× baseline |

| List comprehension | 2,500 | 1.0× (fastest) |

Measured on Python 3.13, single run of 1000 iterations. Comprehensions win because there's no per-element function call — the expression is inlined.

That said: do not micro-optimise. For a 100-element list, all three complete in under 100µs. Pick readability first.

The four patterns you should recognise

1. Transform every element

▶ PYTHONeditable · runs in your browser

Drop-in replacement for map(str.title, names) but doesn't need list(...) wrapping.

2. Filter without transforming

▶ PYTHONeditable · runs in your browser

Cleaner than list(filter(lambda n: n > 0, numbers)). No lambda needed.

3. Filter AND transform

▶ PYTHONeditable · runs in your browser

This is where comprehensions clearly beat the alternatives — try writing it with map + filter and count the parentheses.

4. Flatten a nested list

▶ PYTHONeditable · runs in your browser

Order matters: for row in matrix reads left-to-right like the equivalent nested for loops. This is the only pattern where nested comprehensions stay readable — anything deeper needs a loop.

When to STOP using comprehensions

Three hard rules, in order of importance:

1. Three or more `for` clauses → use a loop. A triply-nested comprehension is unreadable even to the person who wrote it 20 minutes ago.

▶ PYTHONeditable · runs in your browser

2. Side effects → use a loop. Comprehensions are for building a list. If you're calling a function for its side effects (writing to a file, sending a request), use a loop. [print(x) for x in items] is a code smell — you're creating a throwaway list of Nones.

3. The expression is longer than 60 characters → break it up. If you need to think for more than 3 seconds to parse it, split into a named function or a loop.

Dict and set comprehensions — same shape

Same syntax, different brackets:

▶ PYTHONeditable · runs in your browser

Dict comprehensions are especially useful for inverting a mapping ({v: k for k, v in d.items()}) or building a lookup table from a list.

Generator expressions — the memory-friendly cousin

Drop the brackets, keep the parentheses:

▶ PYTHONeditable · runs in your browser

For sum, min, max, any, all, ", ".join(...), and other functions that iterate once, prefer the generator expression — it saves the intermediate list allocation. For anything you need to index or iterate twice, use a comprehension.

Practice: three exercises

Rewrite each using a list comprehension. Solutions are at the end.

1. Given words = ["cat", "elephant", "dog", "hippopotamus"], get a list of words longer than 4 characters, all in uppercase.

2. Given data = [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}], extract a list of just the names.

3. Given pairs = [(1, 2), (3, 4), (5, 6)], get a list of the sums of each pair.

Solutions:

▶ PYTHONeditable · runs in your browser

List comprehensions are a signature Python feature — knowing when to reach for one (and when to leave it as a for loop) is a reliable marker of intermediate-level fluency. Practice by rewriting existing for + .append loops you find in your own code; not every one should become a comprehension, but the ones that should will feel obvious after a week.

Next step: try 5 interactive lessons on list comprehensions with real Python running in your browser and an AI mentor on every step.

Ready to try it?

15 lessons free after a free signup — no card. Sample the platform, then decide.

Start free

Or unlock every lesson

Pro — $12/mo, unlimited AI, cancel any time. Refund within 14 days worldwide.

See Pro plans

Get one Python lesson + one career idea every Friday

No spam, no "buy our course now". Three bullets, every Friday. Unsubscribe with one click.