Programming

Python List Comprehension: 15 Examples, Simple to Advanced

The three-slot pattern that folds a loop into one readable line, explained from zero with 15 tested examples.

Modern Age Coders
Modern Age Coders July 3, 2026
9 min read
Python list comprehension explained with 15 examples from simple to advanced

There is a moment in every Python learner's life when a four-line loop collapses into one clean line, and the code suddenly reads like a sentence. That is list comprehension, and it is less magic than it looks: a loop, folded into the brackets of the list it builds.

Comprehensions matter for two reasons. They are everywhere in real Python code, so you have to read them fluently even if you never write one. And when used well they are genuinely clearer than the loops they replace, because the whole intent sits on a single line.

This guide builds the idea from zero and then works through 15 examples, each one executed before it was pasted here. You only need loops and lists to follow along; if those are still new, start with Python for beginners and come back.

The Pattern Behind Every Comprehension

Every list comprehension has the same three slots: an expression that shapes each item, a for clause that walks a sequence, and an optional if that filters. Once you can spot the three slots, you can read any comprehension ever written.

Anatomy of a Python list comprehension with the expression, loop, and filter parts labelled
Three slots: shape it, walk it, filter it. The if is optional.

Here is the same job done both ways. The loop appends item by item. The comprehension says the whole thing at once.

A four-line Python for loop and a one-line list comprehension producing exactly the same list
Same output, same speed of thought once you can read it.

A good way to hold the idea: a comprehension is a conveyor belt. Items ride in from the sequence, the if gate drops the ones that do not qualify, the expression reshapes the ones that pass, and the finished items land in a new list. The original list is never touched.

List comprehension as a conveyor belt: numbers flow in, a filter gate drops the odd ones, the expression doubles the rest
In, filter, transform, out. The source list stays exactly as it was.

The Basics, One Idea at a Time

Five examples, each adding one small twist: transform, filter, and the fact that any sequence can feed a comprehension. Read every one aloud before running it.

1. Squares from a range

The hello world of comprehensions. Read it right to left: for every n from 1 to 5, keep n times n.

squares = [n * n for n in range(1, 6)]

print(squares)
[1, 4, 9, 16, 25]

2. Transform every item

Any expression works at the front. Here each name passes through upper() on its way into the new list.

names = ["asha", "rohan", "meera"]

shouty = [name.upper() for name in names]

print(shouty)
['ASHA', 'ROHAN', 'MEERA']

3. Filter with an if at the end

Add an if after the loop and only the items that pass get in. Nothing is transformed here, just selected.

numbers = [4, 7, 10, 13, 16, 19]

evens = [n for n in numbers if n % 2 == 0]

print(evens)
[4, 10, 16]

4. Pull characters from a string

Strings are sequences too, so a comprehension can walk one letter at a time.

word = "programming"

vowels = [ch for ch in word if ch in "aeiou"]

print(vowels)
['o', 'a', 'i']

5. Convert a whole list of types

Input usually arrives as text. One line turns a list of digit strings into real numbers you can add.

raw = ["10", "25", "7"]

nums = [int(s) for s in raw]

print(nums)
print(sum(nums))
[10, 25, 7]
42

Everyday Jobs

The examples you will actually reuse: labelling data, cleaning text, and flattening the awkward nested lists that real programs keep handing you.

Where the if goes in a Python list comprehension: a filtering if sits after the loop, an if-else expression sits before it
The one everyone mixes up. A filtering if goes at the end. An if-else that produces a value goes at the front.

6. Label items with if-else

When every item must produce something, the if-else moves to the front, before the for. It is an expression now, not a filter.

marks = [35, 72, 48, 91, 28]

results = ["pass" if m >= 40 else "fail" for m in marks]

print(results)
['fail', 'pass', 'pass', 'pass', 'fail']

7. Clean up messy text

Real data arrives with stray spaces and random capitals. Chain the string methods inside the expression and the whole list comes out washed.

raw = ["  Asha ", "ROHAN", " meera  "]

clean = [s.strip().lower() for s in raw]

print(clean)
['asha', 'rohan', 'meera']

8. Measure every word

A comprehension can hand its result straight to another function, like max() hunting for the longest word.

words = ["code", "python", "loop", "comprehension"]

lengths = [len(w) for w in words]

print(lengths)
print(max(lengths))
[4, 6, 4, 13]
13

9. Flatten a nested list

Two fors run left to right, exactly in the order you would write them as normal loops: first each row, then each item inside it.

nested = [[1, 2], [3, 4], [5, 6]]

flat = [x for row in nested for x in row]

print(flat)
[1, 2, 3, 4, 5, 6]

10. Build every pair

Two independent loops give you every combination, the same way a times table is built.

pairs = [(x, y) for x in [1, 2, 3] for y in ["a", "b"]]

print(pairs)
[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]

Sharper Tools

The last five push further: matrices, dictionaries, and the set, dict, and generator cousins that share the same shape.

11. Grab one column from a matrix

A matrix is a list of rows. Picking index 1 from every row slices out the middle column.

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

column = [row[1] for row in matrix]

print(column)
[2, 5, 8]

12. Filter a dictionary into a list

Comprehensions read from anything you can loop over, including dictionary items. Here only the passing students keep their names on the list.

results = {"Asha": 92, "Rohan": 35, "Meera": 78, "Zoya": 38}

passed = [name for name, m in results.items() if m >= 40]

print(passed)
['Asha', 'Meera']

13. Keep only the digits

Combine a filter with join() and you have a one-line text cleaner.

messy = "a1b2c3d4"

digits = "".join([ch for ch in messy if ch.isdigit()])

print(digits)
1234

14. Meet the cousins: set and dict comprehensions

Swap the square brackets for braces and the same pattern builds sets and dictionaries. One idea, three containers.

words = ["code", "loop", "python", "trees"]

unique_lengths = {len(w) for w in words}
word_length = {w: len(w) for w in words}

print(unique_lengths)
print(word_length)
{4, 5, 6}
{'code': 4, 'loop': 4, 'python': 6, 'trees': 5}

15. Drop the brackets and feed sum() directly

Without brackets this becomes a generator expression: it never builds the list in memory, it just streams values into sum(). For big ranges this is the version to use.

total = sum(n * n for n in range(1, 101))

print(total)
338350

When a Plain Loop Is the Better Choice

Comprehensions are for building lists, not for doing things. If the body of your loop prints, saves to a file, or updates other variables, keep it as a loop. And if your comprehension needs more than one if and one or two fors to say what it means, it has outgrown one line. The test is simple: can you read it aloud in one breath? If not, write the loop. Nobody was ever failed in a code review for being too clear.

๐Ÿ’ก

Read it aloud

Every comprehension can be spoken as a sentence. [n * n for n in range(1, 6)] reads as: the square of every n from 1 to 5. If you cannot phrase yours as a sentence, that is the sign to break it back into a loop.

Mistakes That Catch Everyone Once

  • Putting a filtering if before the for: [n for n if n > 0 in nums] is a syntax error. A filter goes after the loop: [n for n in nums if n > 0].
  • Forgetting the else in a front if: ["pass" if m >= 40 for m in marks] fails. An if before the for is an expression and must carry an else.
  • Using a comprehension for side effects: [print(x) for x in items] builds a useless list of None. Just write the loop.
  • Nesting until unreadable: two fors is the practical ceiling. Three or more belongs in a loop with real names.
  • Shadowing names: [x for x in x] runs but hurts. Give the loop variable its own name.

Frequently Asked Questions

A compact way to build a new list by transforming and filtering an existing sequence in one expression: [n * n for n in range(1, 6)] builds the squares of 1 to 5. It does the same work as a for loop with append, folded into a single readable line.

Usually a little faster, because the looping happens in Python's internals rather than through repeated append calls. But the honest reason to use one is readability, not speed. For heavy number crunching, libraries like NumPy matter far more than loop style.

A filtering if goes at the end, after the for: [n for n in nums if n > 0]. An if-else that chooses a value goes at the front, before the for: ["pass" if m >= 40 else "fail" for m in marks]. The two are different tools and the position is what separates them.

Yes, but only in the front position as part of a conditional expression: value_if_true if condition else value_if_false. A trailing filter if cannot take an else, which is the error most beginners hit first.

Multiple fors read left to right in the same order as stacked loops. [x for row in nested for x in row] means: for each row in nested, for each x in that row, keep x. That flattens a list of lists.

Brackets build the whole list in memory at once. Parentheses, or no brackets inside a function call like sum(n * n for n in range(1000000)), create a generator that produces one value at a time. For large data, the generator saves memory.

Yes. Braces build a set: {len(w) for w in words}. Braces with a colon build a dictionary: {w: len(w) for w in words}. The reading pattern is identical, only the container changes.

One Pattern, a Lifetime of Use

Fifteen examples, but really one pattern: shape it, walk it, filter it. From here, comprehensions turn up everywhere, filtering rows of data, cleaning text, and feeding results straight into sum(), max(), and friends. Keep practising with our dictionary guide, which pairs naturally with this one, or flex the basics with 30 pattern programs.

If you want this level of Python to become second nature, our Python from the ground up course builds it brick by brick, and our live coding courses teach learners aged 6 to 67 with a real teacher reading every line.

Related reading

Modern Age Coders

About Modern Age Coders

Expert educators passionate about making coding accessible and fun for learners of all ages.

Ask Misti AI
Chat with us