In our last article, we used filter()
to extract even numbers from a list. It worked, but it required a lambda
and wrapping the result in list()
. There's a more expressive, more Pythonic way to do this: the list comprehension.
A list comprehension is a concise, readable way to create a new list by processing or filtering the items in an existing iterable. Think of it as a streamlined factory assembly line for your data: items are fed in, optionally inspected, transformed, and packaged into a new list—all in a single, efficient line of code.
The Basic Pattern: Transforming Data
Let's start with the classic loop method for creating a new list and see how a comprehension simplifies it.
The "Long Way" (with a for-loop):
numbers = [1, 2, 3, 4, 5]
squares = []
for num in numbers:
squares.append(num ** 2)
print(squares) # Output: [1, 4, 9, 16, 25]
The Pythonic Way (with a list comprehension):
numbers = [1, 2, 3, 4, 5]
squares = [num ** 2 for num in numbers] # Transform each element
print(squares) # Output: [1, 4, 9, 16, 25]
The structure is simple: [new_value for item in iterable]
. It reads almost like English: "Give me a list of 'num squared' for every 'num' in 'numbers'." Not only is this more readable, but it's also often faster than building a list with a loop, especially for large datasets.
Level 2: Adding Filtering with if
What if you only want to transform some of the items? This is where list comprehensions truly shine, replacing the need for filter()
in many cases.
Recall the filter()
example for even numbers:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
evens = list(filter(lambda x: x % 2 == 0, numbers))
Here’s the clearer, comprehension-based approach:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
evens = [num for num in numbers if num % 2 == 0] # Filter and include
print(evens) # Output: [2, 4, 6, 8]
The structure now is: [item for item in iterable if condition]
. It reads: "Give me a list of 'num' for every 'num' in 'numbers' **if* the number is even."* No lambda
needed!
Level 3: Transforming Filtered Data
You can combine both transformation and filtering in a single, powerful line. The order of operations is crucial: [<what to output> for <item> in <iterable> if <condition>]
. The <condition>
acts as a filter, and the <what to output>
transforms the items that pass.
Task: Get the squares of all even numbers.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
squares_of_evens = [num ** 2 for num in numbers if num % 2 == 0]
print(squares_of_evens) # Output: [4, 16, 36, 64]
This is far more concise and readable than writing a loop that checks a condition and then appends a transformed value.
Beyond Lists: Comprehension Power
The comprehension pattern is so beloved in Python that it was extended to other data structures, promoting consistency across the language.
Dictionary Comprehension:
# Create a dictionary mapping numbers to their squares
numbers = [1, 2, 3, 4]
squares_dict = {num: num**2 for num in numbers}
print(squares_dict) # Output: {1: 1, 2: 4, 3: 9, 4: 16}
Set Comprehension:
# Create a set of unique squares (duplicates are automatically removed)
numbers = [1, 2, 2, 3, 4]
unique_squares = {num**2 for num in numbers}
print(unique_squares) # Output: {1, 4, 9, 16}
When to Stick with a Loop
List comprehensions are brilliant, but they aren't always the answer. Prioritize readability.
- Use a comprehension for simple transforming and/or filtering. They are perfect for these tasks.
-
Use a traditional for-loop when the logic is complex, you need multiple conditions, or you need to use statements like
print()
orbreak
within the loop.
Your New Superpower
You now have a powerful tool for writing elegant, efficient, and Pythonic code. The list comprehension is a hallmark of an experienced Python developer. Remember its simple syntax:
- Transform:
[<expression> for <item> in <iterable>]
- Filter:
[<item> for <item> in <iterable> if <condition>]
- Transform & Filter:
[<expression> for <item> in <iterable> if <condition>]
Use them to make your code cleaner, faster, and a joy to read.
Up Next: We've mastered creating and filtering data. Now let's learn how to navigate it effortlessly by exploring Slicing and Indexing in Python to access any part of your lists and strings with precision.
Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.
Top comments (0)