Web Analytics

List Comprehensions

Intermediate ~25 min read

List comprehensions are one of Python's most beloved features - they let you create new lists by transforming and filtering existing iterables in a single, elegant line of code. Once you learn them, you'll wonder how you ever lived without them!

Basic List Comprehension

The basic syntax is [expression for item in iterable]. It's equivalent to a for loop that appends to a list, but more concise and often faster.

Output
Click Run to execute your code
Why Use List Comprehensions? They're not just shorter - they're often faster than equivalent for loops because Python optimizes them internally. They're also considered more "Pythonic" - the preferred Python style for creating lists.

Filtering with Conditions

Add an if clause at the end to filter items: [expr for item in iterable if condition]. Only items that satisfy the condition are included in the result.

Output
Click Run to execute your code
Pro Tip: The filtering if goes at the END of the comprehension (after for). This filters which items to include. Don't confuse it with the if-else ternary expression, which goes at the BEGINNING and transforms values.

If-Else Transformation

Use the ternary expression true_expr if condition else false_expr as your expression to transform items differently based on a condition. This goes BEFORE the for.

Output
Click Run to execute your code
Position Matters! Filtering if (no else) goes at the END: [x for x in nums if x > 0]. Ternary if-else goes at the START: [x if x > 0 else 0 for x in nums]. Mixing them up is a common source of syntax errors!

Nested List Comprehensions

You can nest comprehensions to work with 2D data. Read them left-to-right: the outer loop comes first, then the inner loop.

Output
Click Run to execute your code

Common Mistakes

1. Wrong position for if vs if-else

# Wrong - filter if with else
evens = [x if x % 2 == 0 for x in nums]  # SyntaxError!

# Correct - filter if (no else) goes at end
evens = [x for x in nums if x % 2 == 0]

# Correct - ternary if-else goes at start
labels = [x if x % 2 == 0 else "odd" for x in nums]

2. Overcomplicating with too much nesting

# Hard to read - too complex
result = [[y*2 for y in x if y > 0] for x in matrix if sum(x) > 5]

# Better - break into steps or use regular loops
filtered_rows = [row for row in matrix if sum(row) > 5]
result = [[y*2 for y in row if y > 0] for row in filtered_rows]

3. Forgetting that comprehensions create NEW lists

# Wrong - expecting in-place modification
numbers = [1, 2, 3]
[x * 2 for x in numbers]  # Creates new list, thrown away!
print(numbers)  # Still [1, 2, 3]

# Correct - assign the result
numbers = [x * 2 for x in numbers]
print(numbers)  # [2, 4, 6]

4. Variable scope leaking (Python 2 issue)

# In Python 3, comprehension variables are scoped
x = 10
squares = [x**2 for x in range(5)]
print(x)  # Still 10 in Python 3!

# This was a bug in Python 2 where x would become 4
# Python 3 fixed this - comprehension variables stay local

Exercise: Filtering and Transforming

Task: Use list comprehensions to process a list of words.

Requirements:

  • Create a list of the length of each word
  • Create a list of words longer than 5 characters
Output
Click Run to execute your code
Show Solution
words = ["apple", "banana", "cherry", "date", "elderberry"]

# List of lengths
lengths = [len(word) for word in words]
print(f"Lengths: {lengths}")  # [5, 6, 6, 4, 10]

# Words longer than 5 characters
long_words = [word for word in words if len(word) > 5]
print(f"Long words: {long_words}")  # ['banana', 'cherry', 'elderberry']

Summary

  • Basic: [expr for item in iterable]
  • Filter: [expr for item in iterable if condition]
  • Transform: [true_expr if cond else false_expr for item in iterable]
  • Nested: [expr for outer in iterable1 for inner in iterable2]
  • Position: Filter if at END, ternary if-else at START
  • Benefits: More concise, often faster, more Pythonic
  • Readability: If it's too complex, use a regular loop instead

What's Next?

Now let's learn about Tuples - Python's immutable sequence type. They're like lists that can't be changed, which makes them perfect for data that shouldn't be modified!