Python - Python Comprehensions: List, Set, and Dictionary Comprehensions
Python comprehensions provide a concise way to create new collections from existing iterables such as lists, tuples, strings, ranges, and other iterable objects. Instead of writing several lines with a for loop and repeatedly calling methods such as append(), a comprehension allows the same operation to be expressed in a single readable statement. Python mainly provides three collection comprehensions: list comprehensions, set comprehensions, and dictionary comprehensions. Although their syntax is compact, they can perform filtering, transformation, and conditional processing of data.
1. List Comprehension
A list comprehension creates a new list by processing each element of an iterable.
The basic syntax is:
[expression for item in iterable]
For example:
numbers = [1, 2, 3, 4, 5]
squares = [n * n for n in numbers]
print(squares)
Output:
[1, 4, 9, 16, 25]
Here, n * n is the expression, n is the variable that receives each element, and numbers is the iterable.
The equivalent traditional loop would be:
numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
squares.append(n * n)
print(squares)
Both approaches produce the same result, but the comprehension is more compact.
2. List Comprehension with a Condition
A condition can be added to a list comprehension when only certain elements should be included.
Syntax:
[expression for item in iterable if condition]
For example, to obtain only even numbers:
numbers = range(1, 11)
even_numbers = [n for n in numbers if n % 2 == 0]
print(even_numbers)
Output:
[2, 4, 6, 8, 10]
The if condition determines which elements are included in the resulting list.
Another example:
names = ["Alice", "Bob", "Andrew", "David"]
a_names = [name for name in names if name.startswith("A")]
print(a_names)
Output:
['Alice', 'Andrew']
This demonstrates how comprehensions can be used for filtering data.
3. Transforming Data with List Comprehension
List comprehensions are particularly useful when every element needs to be transformed.
For example:
prices = [100, 200, 300, 400]
discounted = [price * 0.9 for price in prices]
print(discounted)
Output:
[90.0, 180.0, 270.0, 360.0]
The original values remain unchanged, while the comprehension creates a new list containing the transformed values.
A string can also be transformed:
words = ["python", "java", "html"]
uppercase_words = [word.upper() for word in words]
print(uppercase_words)
Output:
['PYTHON', 'JAVA', 'HTML']
4. Conditional Expressions in List Comprehensions
A conditional expression can be used when the output itself should depend on a condition.
For example:
numbers = range(1, 6)
result = ["Even" if n % 2 == 0 else "Odd" for n in numbers]
print(result)
Output:
['Odd', 'Even', 'Odd', 'Even', 'Odd']
This is different from using a filtering condition.
In:
[n for n in numbers if n % 2 == 0]
the condition determines whether an element is included.
In:
["Even" if n % 2 == 0 else "Odd" for n in numbers]
every element is included, but the value placed in the new list depends on the condition.
5. Nested List Comprehensions
A comprehension can contain more than one for clause. This is useful for processing nested collections.
For example:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
flattened = [number for row in matrix for number in row]
print(flattened)
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
The equivalent loops would be:
flattened = []
for row in matrix:
for number in row:
flattened.append(number)
The comprehension provides a compact way to flatten the nested structure.
However, deeply nested comprehensions can become difficult to read. In such cases, normal loops are often preferable.
6. Set Comprehension
A set comprehension creates a set instead of a list.
Its syntax is:
{expression for item in iterable}
For example:
numbers = [1, 2, 2, 3, 3, 4]
squares = {n * n for n in numbers}
print(squares)
Output:
{1, 4, 9, 16}
The duplicate values are automatically removed because sets contain only unique elements.
Another example:
words = ["python", "java", "python", "html"]
lengths = {len(word) for word in words}
print(lengths)
Output:
{4, 6}
The lengths are calculated for each word, and duplicate lengths are stored only once.
Set comprehensions are useful when the resulting data needs to contain unique values.
7. Dictionary Comprehension
Dictionary comprehensions are used to construct dictionaries dynamically.
The basic syntax is:
{key: value for item in iterable}
For example:
numbers = [1, 2, 3, 4, 5]
squares = {n: n * n for n in numbers}
print(squares)
Output:
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
In this example, each number becomes a dictionary key, while its square becomes the corresponding value.
Dictionary comprehensions can also be used to transform an existing dictionary.
prices = {
"book": 200,
"pen": 50,
"bag": 800
}
discounted = {
item: price * 0.9
for item, price in prices.items()
}
print(discounted)
Output:
{'book': 180.0, 'pen': 45.0, 'bag': 720.0}
8. Filtering with Dictionary Comprehension
A condition can also be applied to dictionary comprehensions.
For example:
marks = {
"Alice": 85,
"Bob": 62,
"Charlie": 91,
"David": 55
}
passed = {
name: mark
for name, mark in marks.items()
if mark >= 60
}
print(passed)
Output:
{'Alice': 85, 'Bob': 62, 'Charlie': 91}
Only students whose marks are 60 or higher are included.
9. Difference Between List, Set, and Dictionary Comprehensions
The three types can be distinguished by the collection they produce and their syntax.
| Type | Syntax | Result |
|---|---|---|
| List comprehension | [expression for item in iterable] |
List |
| Set comprehension | {expression for item in iterable} |
Set |
| Dictionary comprehension | {key: value for item in iterable} |
Dictionary |
For example:
numbers = [1, 2, 3, 4]
list_result = [n * 2 for n in numbers]
set_result = {n * 2 for n in numbers}
dict_result = {n: n * 2 for n in numbers}
The results are:
[2, 4, 6, 8]
{2, 4, 6, 8}
{1: 2, 2: 4, 3: 6, 4: 8}
The choice depends on the type of data structure required by the program.
10. Advantages of Comprehensions
Comprehensions can make code shorter and easier to understand when used appropriately. They are especially useful for simple transformations and filtering operations.
They can reduce the amount of repetitive code required for operations such as:
numbers = [1, 2, 3, 4, 5]
result = [n * 10 for n in numbers]
They also clearly express the relationship between the input data and the resulting collection.
Another advantage is that comprehensions can often be more readable than a loop when the operation is simple and straightforward.
11. When Not to Use Comprehensions
Although comprehensions are powerful, they should not be used simply to make every piece of code shorter.
For example, a very complicated comprehension containing several nested loops and conditions can be difficult to understand:
result = [
transform(x, y)
for x in data
if condition1(x)
for y in other_data
if condition2(x, y)
]
In such situations, traditional for loops may be clearer.
The primary goal should be readability, not simply reducing the number of lines.
Conclusion
Python comprehensions provide a concise mechanism for creating lists, sets, and dictionaries from iterable data. List comprehensions are useful for creating and transforming lists, set comprehensions are useful when unique results are required, and dictionary comprehensions are useful for constructing key-value mappings. Conditions can be added to filter data, while conditional expressions can be used to determine the value produced for each element. When the operation is simple, comprehensions can make Python programs concise and readable; when the logic becomes complicated, conventional loops are often the better choice.