List Comprehension
List Comprehension in Python
Learn how to create, transform, filter, and flatten Python lists using concise and readable list-comprehension syntax.
Python programmers frequently create a new list by processing the
values of an existing iterable. A traditional solution usually
requires an empty list, a loop, and one or more calls to
append().
A list comprehension provides a shorter and more expressive way to perform the same operation. It combines an expression, a loop, and an optional condition inside square brackets.
Prerequisites
What You Should Know
- Creating and accessing Python lists
- Using
forloops - Using
ifandelseconditions - Calling functions and methods
- Using operators such as
+,*,%, and comparison operators - Basic understanding of iterable objects
What is List Comprehension?
List comprehension is a Python syntax for creating a new list by evaluating an expression for each item in an iterable.
It can optionally include a condition that determines which items should be included in the resulting list.
Think of it as a processing pipeline
Values enter from an iterable, an optional condition filters them, an expression transforms the accepted values, and the results are collected into a new list.
Basic Syntax
The condition is optional. Therefore, the simplest form is:
new_list = [expression for item in iterable]
The filtering form is:
new_list = [
expression
for item in iterable
if condition
]
Understanding Each Part
| Part | Purpose | Example |
|---|---|---|
| Expression | Calculates the value added to the new list. |
number ** 2
|
| Item | Represents the current value during iteration. |
number
|
| Iterable | Supplies the values to process. |
numbers
|
| Condition | Optionally filters the input values. |
number % 2 == 0
|
Your First List Comprehension
Create a new list containing the same values as an existing list:
numbers = [1, 2, 3, 4, 5]
copied_numbers = [
number
for number in numbers
]
print(copied_numbers)
Output:
[1, 2, 3, 4, 5]
The expression is number. Therefore, every original
value is added to the new list without modification.
Traditional Loop vs List Comprehension
Using a Traditional Loop
numbers = [1, 2, 3, 4, 5]
squares = []
for number in numbers:
squares.append(number ** 2)
print(squares)
Using List Comprehension
numbers = [1, 2, 3, 4, 5]
squares = [
number ** 2
for number in numbers
]
print(squares)
Output:
[1, 4, 9, 16, 25]
append().
Use List Comprehension with range()
Any iterable can supply values to a list comprehension. The
range() function is commonly used for number sequences.
numbers = [
number
for number in range(1, 6)
]
print(numbers)
Output:
[1, 2, 3, 4, 5]
Create squares from 1 through 10:
squares = [
number ** 2
for number in range(1, 11)
]
print(squares)
Output:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Transform List Values
The expression can modify every value before adding it to the new list.
Multiply Every Number
prices = [100, 250, 400]
doubled_prices = [
price * 2
for price in prices
]
print(doubled_prices)
Output:
[200, 500, 800]
Convert Strings to Uppercase
names = ["ravi", "amina", "john"]
uppercase_names = [
name.upper()
for name in names
]
print(uppercase_names)
Output:
['RAVI', 'AMINA', 'JOHN']
Filter Values with if
An if condition placed after the iterable acts as a
filter. Only values for which the condition is true are processed.
Create a list containing only even numbers:
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = [
number
for number in numbers
if number % 2 == 0
]
print(even_numbers)
Output:
[2, 4, 6, 8]
Filter String Values
Select names that begin with the letter A:
names = [
"Amina",
"Rahul",
"Anita",
"David",
"Arif"
]
names_starting_with_a = [
name
for name in names
if name.startswith("A")
]
print(names_starting_with_a)
Output:
['Amina', 'Anita', 'Arif']
Filter words whose length is greater than five:
words = [
"python",
"code",
"developer",
"list",
"function"
]
long_words = [
word
for word in words
if len(word) > 5
]
print(long_words)
Output:
['python', 'developer', 'function']
Transform and Filter Together
A comprehension can filter the input and transform the accepted values in the same expression.
numbers = [1, 2, 3, 4, 5, 6]
even_squares = [
number ** 2
for number in numbers
if number % 2 == 0
]
print(even_squares)
Output:
[4, 16, 36]
In this example, odd numbers are rejected. The accepted even numbers are squared before being added to the resulting list.
Use if-else in the Expression
An inline conditional expression can produce one value when a condition is true and another value when it is false.
numbers = [1, 2, 3, 4, 5, 6]
labels = [
"Even" if number % 2 == 0 else "Odd"
for number in numbers
]
print(labels)
Output:
['Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even']
if-else chooses the output value, it appears
before the for clause. A filtering
if appears after the iterable.
Filtering if vs Conditional if-else
| Type | Purpose | Position |
|---|---|---|
Filtering if
|
Decides whether an input item is included. | After the iterable |
Conditional if-else
|
Decides which output value is generated. |
Before the for clause
|
Filtering Example
result = [
number
for number in range(10)
if number % 2 == 0
]
Conditional Output Example
result = [
"Even" if number % 2 == 0 else "Odd"
for number in range(10)
]
Call a Function in List Comprehension
The expression may contain a function call.
def calculate_discount(price):
return round(price * 0.90, 2)
prices = [100, 250, 500]
discounted_prices = [
calculate_discount(price)
for price in prices
]
print(discounted_prices)
Output:
[90.0, 225.0, 450.0]
Work with a List of Dictionaries
Consider a list containing employee records:
employees = [
{"name": "Amina", "active": True},
{"name": "Rahul", "active": False},
{"name": "David", "active": True},
]
active_employee_names = [
employee["name"]
for employee in employees
if employee["active"]
]
print(active_employee_names)
Output:
['Amina', 'David']
Use Multiple Conditions
Combine conditions with logical operators:
numbers = range(1, 31)
selected_numbers = [
number
for number in numbers
if number % 2 == 0 and number % 3 == 0
]
print(selected_numbers)
Output:
[6, 12, 18, 24, 30]
List Comprehension with Nested Loops
A list comprehension can contain more than one
for clause.
Create coordinate pairs:
coordinates = [
(row, column)
for row in range(1, 3)
for column in range(1, 4)
]
print(coordinates)
Output:
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)]
The equivalent traditional loops are:
coordinates = []
for row in range(1, 3):
for column in range(1, 4):
coordinates.append((row, column))
print(coordinates)
for clauses in the comprehension
follows the order of the equivalent nested loops.
Flatten a Nested List
Flattening converts a nested list into one list of values.
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
flattened = [
value
for row in matrix
for value in row
]
print(flattened)
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Create a Matrix
A nested comprehension can create a list containing other lists:
matrix = [
[
column
for column in range(1, 4)
]
for row in range(3)
]
print(matrix)
Output:
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
Process Characters from a String
A string is iterable, so its individual characters can be processed.
text = "Python 3.14"
letters = [
character.upper()
for character in text
if character.isalpha()
]
print(letters)
Output:
['P', 'Y', 'T', 'H', 'O', 'N']
Handle Invalid Input Safely
Avoid placing complicated exception-handling logic inside a list comprehension. Move that logic into a named function.
def convert_to_integer(value):
try:
return int(value)
except ValueError:
return None
values = ["10", "25", "invalid", "40"]
converted_values = [
convert_to_integer(value)
for value in values
]
print(converted_values)
Output:
[10, 25, None, 40]
List Comprehension and Memory
A list comprehension creates the complete result list in memory. This is appropriate when the resulting list is required for later indexing, repeated iteration, or modification.
squares = [
number ** 2
for number in range(1, 1001)
]
When values need to be processed one at a time rather than stored immediately, a generator expression may be more appropriate:
square_generator = (
number ** 2
for number in range(1, 1001)
)
| Feature | List Comprehension | Generator Expression |
|---|---|---|
| Brackets | Square brackets | Parentheses |
| Evaluation | Creates the result list immediately | Produces values when requested |
| Result | A list | A generator object |
When to Use List Comprehension
Good Use Cases
- Creating a list from an existing iterable
- Applying a simple transformation to every item
- Filtering values using a short condition
- Transforming and filtering in one readable expression
- Flattening a simple nested structure
- Replacing a short append-based loop
When Not to Use List Comprehension
Prefer a Normal Loop When
- The expression contains complicated business logic.
- Multiple statements must run for every item.
- Detailed exception handling is required.
- Several nested loops make the code difficult to follow.
- The operation exists mainly for side effects.
- Debugging requires intermediate values or breakpoints.
Poor and Readable Comprehensions
Difficult to Read
- Multiple nested transformations
- Several unrelated conditions
- Unclear single-letter variable names
- Hidden function side effects
- Too much logic inside one expression
Easy to Read
- One clear transformation
- One short filtering condition
- Descriptive variable names
- Pure expression without side effects
- Formatting across multiple lines when needed
Practical Example: Eligible Orders
Consider a list of customer orders. We want the order numbers for completed orders worth at least 1,000.
orders = [
{
"order_number": "ORD-101",
"amount": 750,
"completed": True,
},
{
"order_number": "ORD-102",
"amount": 1500,
"completed": True,
},
{
"order_number": "ORD-103",
"amount": 1800,
"completed": False,
},
{
"order_number": "ORD-104",
"amount": 2200,
"completed": True,
},
]
eligible_order_numbers = [
order["order_number"]
for order in orders
if order["completed"] and order["amount"] >= 1000
]
print(eligible_order_numbers)
Output:
['ORD-102', 'ORD-104']
Common Mistakes
Incorrect Clause Order
for clause.
[expression for item in iterable if condition]
Confusing Filtering with if-else
[item for item in values if condition]
[value_a if condition else value_b for item in values]
Using append() Inside the Expression
A comprehension already builds and returns a new list.
append().
Creating an Unused List
Using list comprehension only to call a function for its side effects creates an unnecessary list.
for loop when the result list is not
needed.
Hands-On Practice
Practice Exercises
- Create a list containing cubes from 1 through 10.
- Extract all odd numbers from a list.
- Convert a collection of names to title case.
- Select words containing more than six characters.
- Create labels indicating whether numbers are positive, negative, or zero.
- Flatten a two-dimensional list.
- Create coordinate pairs from two ranges.
- Extract active employee names from a list of dictionaries.
Knowledge Check
What does a list comprehension produce?
It evaluates its expression and collects the resulting values into a new list.
Is the filtering condition mandatory?
No. The filtering if condition is optional.
How do you create squares from 1 through 5?
squares = [
number ** 2
for number in range(1, 6)
]
How do you select only even numbers?
even_numbers = [
number
for number in numbers
if number % 2 == 0
]
When should a normal loop be preferred?
Prefer a normal loop when the operation contains complex logic, several statements, detailed exception handling, or significant side effects.
List Comprehension Quick Reference
# Copy values
result = [item for item in iterable]
# Transform values
result = [transform(item) for item in iterable]
# Filter values
result = [
item
for item in iterable
if condition
]
# Transform and filter
result = [
transform(item)
for item in iterable
if condition
]
# Conditional output
result = [
value_if_true if condition else value_if_false
for item in iterable
]
# Nested loops
result = [
expression
for outer_item in outer_iterable
for inner_item in inner_iterable
]
# Flatten nested lists
flattened = [
item
for row in nested_list
for item in row
]
Summary
What You Learned
- List comprehension provides concise syntax for creating new lists.
- The expression determines the value added to the result.
- A filtering condition determines which input values are accepted.
- An inline if-else expression selects between output values.
- Functions and methods can be called inside the expression.
- Multiple for clauses can represent nested loops.
- A comprehension can flatten a simple nested list.
- Normal loops are preferable when comprehension logic becomes difficult to understand.
Key Takeaway
Use list comprehension when a list can be created through a clear transformation, an optional filter, and a readable iteration. If the logic becomes complicated, choose a normal loop to preserve clarity.