Python list comprehension examples

A list comprehension says what to produce, which loop supplies the items, and optionally which items survive. The short form is useful, but it has a hard readability limit. These examples show both the grammar and where to stop.

🎙️ Published & recorded: ·

The core four

Start in the middle with for n in nums, then read the expression on the left as the output. A filtering if goes at the far right and can drop an item. An if-else goes before the for because it chooses the output value while keeping every item.

nums = [1, 2, 3, 4, 5]

[n * n for n in nums]                # transform → [1,4,9,16,25]
[n for n in nums if n % 2 == 0]     # filter → [2,4]
[n*n for n in nums if n > 2]        # both → [9,16,25]
["even" if n%2==0 else "odd" for n in nums]  # choose

The position changes the meaning. Right-side if means keep or discard. Left-side if-else means choose this value or that value.

Real-world one-liners

Good comprehensions perform one recognizable transformation with at most one simple filter. Cleaning non-empty strings and selecting active users' email fields pass that test. Filename filtering also reads naturally because the condition sits beside the loop it controls.

# clean strings and discard blanks
[s.strip().lower() for s in raw if s.strip()]

# pull a field from active API users
[u["email"] for u in users if u["active"]]

# parse numeric fields
[float(x) for x in fields]

# filenames matching a suffix
[f for f in os.listdir(".") if f.endswith(".csv")]

For actual CSV data, do not create fields with line split comma; quoted commas break that shortcut. Feed the row through Python's CSV module first, then use a comprehension to convert the already parsed fields.

Dicts, sets, and one-level flattening

Curly braces with a key and value create a dictionary. Curly braces with one expression create a set and remove duplicates. To flatten one nested level, write the for clauses in the same left-to-right order as the equivalent nested loops: first each row, then each item in that row.

{w: len(w) for w in words}            # dict: word → length
{u["id"]: u for u in users}          # index records by id
{n % 3 for n in nums}                # set: unique values
{v: k for k, v in d.items()}         # invert a dict

matrix = [[1, 2], [3, 4], [5]]
[x for row in matrix for x in row]   # [1,2,3,4,5]

One flattening level is a reasonable ceiling. Add another nested level or a condition and the reader has to mentally execute the code. Write the loops out instead.

Syntax errors, generators, and the stop line

The most common failed rewrite puts else after a filtering condition. Python reports SyntaxError: invalid syntax because a right-side filter has no else branch. Move the whole if-else expression to the left of the for. If you only want matching items, delete else and keep the right-side if.

[n for n in nums if n % 2 == 0 else 0]
# SyntaxError: invalid syntax

[ n if n % 2 == 0 else 0 for n in nums ]  # choose
[ n for n in nums if n % 2 == 0 ]         # filter

sum(n*n for n in nums)   # generator; no intermediate list
Where to stop
A comprehension builds a collection. [print(x) for x in items] allocates a useless list of None; use a normal loop for side effects. Also switch to a loop when there are two conditions, exception handling, or a comment needed to explain the expression.

When sum, max, any, or all can consume values directly, remove the square brackets and use a generator expression. It avoids storing a temporary list. Do that for memory, not to squeeze complicated logic onto one line.

📚 This is one page of our Python series. The full crash course (with audio for your commute): Python in 10 Minutes →

Tell me what missed

A correction is more useful than a compliment. This goes straight to the person who writes SwiftGrasp.

Was this page useful?
0/1000

Please do not include passwords, private keys, or personal information.