Comprehensions in Python provide a concise and efficient way to create new sequences (lists, sets, and dictionaries) from existing iterables. They often make code more readable and can be faster than traditional for
loops for certain operations.
There are three main types of comprehensions:
- List Comprehensions
- Set Comprehensions
- Dictionary Comprehensions
Let's explore each one with examples:
1. List Comprehensions
List comprehensions are used to create new lists.
Basic Syntax:
[expression for item in iterable if condition]
expression
: The operation to perform on eachitem
. This determines what will be added to the new list.item
: The variable that represents each element from theiterable
.iterable
: The source sequence (e.g., list, tuple, string, range) you're iterating over.if condition
(optional): A filter that includes only items for which the condition isTrue
.
Examples:
a) Simple Transformation: Create a list of squared numbers.
numbers = [1, 2, 3, 4, 5]
# Using a for loop:
squared_numbers_loop = []
for num in numbers:
squared_numbers_loop.append(num ** 2)
print(f"Using for loop: {squared_numbers_loop}")
# Using a list comprehension:
squared_numbers_comp = [num ** 2 for num in numbers]
print(f"Using list comprehension: {squared_numbers_comp}")
b) Filtering and Transformation: Create a list of even numbers doubled.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Using a for loop:
even_doubled_loop = []
for num in numbers:
if num % 2 == 0:
even_doubled_loop.append(num * 2)
print(f"Using for loop: {even_doubled_loop}")
# Using a list comprehension:
even_doubled_comp = [num * 2 for num in numbers if num % 2 == 0]
print(f"Using list comprehension: {even_doubled_comp}")
c) With if-else
(Conditional Expression): This is different from the filtering if
. Here, the expression
itself changes based on a condition.
numbers = [1, 2, 3, 4, 5]
# Replace even numbers with "Even", odd numbers with "Odd"
even_or_odd = ["Even" if num % 2 == 0 else "Odd" for num in numbers]
print(even_or_odd)
# Output: ['Odd', 'Even', 'Odd', 'Even', 'Odd']
d) Nested List Comprehensions: For creating lists of lists or flattening nested lists.
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# Flatten the matrix into a single list
flattened_list = [num for row in matrix for num in row]
print(flattened_list)
# Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Create a new matrix where each number is doubled
doubled_matrix = [[num * 2 for num in row] for row in matrix]
print(doubled_matrix)
# Output: [[2, 4, 6], [8, 10, 12], [14, 16, 18]]
2. Set Comprehensions
Set comprehensions are similar to list comprehensions but create new sets. Sets automatically handle uniqueness, so duplicate elements are discarded.
Basic Syntax:
{expression for item in iterable if condition}
Examples:
a) Unique Characters from a String:
text = "hello world"
# Using a set comprehension to get unique characters
unique_chars = {char for char in text if char.isalpha()} # only letters
print(unique_chars)
# Output (order may vary as sets are unordered): {'o', 'd', 'e', 'l', 'r', 'h', 'w'}
b) Squares of Unique Even Numbers:
numbers = [1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8]
# Get squares of unique even numbers
unique_even_squares = {num ** 2 for num in numbers if num % 2 == 0}
print(unique_even_squares)
# Output: {64, 4, 16, 36} (order varies)
3. Dictionary Comprehensions
Dictionary comprehensions are used to create new dictionaries.
Basic Syntax:
{key_expression: value_expression for item in iterable if condition}
key_expression
: The expression that determines the key for each item.value_expression
: The expression that determines the value for each item.
Examples:
a) Creating a Dictionary from Lists (using zip
):
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 22]
# Create a dictionary mapping names to ages
name_age_dict = {name: age for name, age in zip(names, ages)}
print(name_age_dict)
# Output: {'Alice': 25, 'Bob': 30, 'Charlie': 22}
b) Squaring Numbers in a Dictionary (key as original, value as square):
numbers = [1, 2, 3, 4, 5]
# Create a dictionary where keys are numbers and values are their squares
squared_dict = {num: num ** 2 for num in numbers}
print(squared_dict)
# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
c) Filtering a Dictionary:
original_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Create a new dictionary with only even values
even_values_dict = {key: value for key, value in original_dict.items() if value % 2 == 0}
print(even_values_dict)
# Output: {'b': 2, 'd': 4}
4. Generator Expressions (Tuple Comprehensions)
While there isn't a direct "tuple comprehension" syntax that creates a tuple directly, using parentheses ()
around a comprehension creates a generator expression. This is very memory-efficient, especially for large datasets, because it generates values one at a time on demand (lazily) rather than creating the entire sequence in memory at once.
Syntax:
(expression for item in iterable if condition)
Example:
numbers = [1, 2, 3, 4, 5]
# This creates a generator object, not a tuple directly
gen_expr = (num ** 2 for num in numbers)
print(gen_expr)
# Output: <generator object <genexpr> at 0x...>
# You can iterate over it or convert it to a list/tuple if needed
print(list(gen_expr))
# Output: [1, 4, 9, 16, 25]
# Note: Once a generator is exhausted, you can't iterate over it again.
print(list(gen_expr)) # This will print an empty list because it's exhausted
# Output: []
Advantages of Using Comprehensions:
- Conciseness: They allow you to write compact and often single-line code for common data transformations.
- Readability: When used appropriately, they can make your code more readable by clearly expressing the intent.
- Efficiency: Comprehensions are often implemented in C under the hood, making them generally faster than equivalent
for
loops, especially for large datasets. - Reduced Boilerplate: They eliminate the need for initializing an empty list/set/dictionary and then explicitly appending/adding elements in a loop.
When to Use Comprehensions:
- When you need to create a new list, set, or dictionary based on an existing iterable.
- When the logic for transformation and/or filtering is relatively straightforward.
When to Avoid Comprehensions:
- When the logic becomes too complex or involves multiple nested loops with complex conditions. In such cases, a traditional
for
loop might be more readable. - If you're dealing with extremely large datasets and need to process elements one by one without holding the entire result in memory (use generator expressions instead of list/set/dict comprehensions).
By mastering comprehensions, you can write more elegant, efficient, and Pythonic code.
0 件のコメント:
コメントを投稿