List Comprehensions
List comprehensions streamline list construction from existing iterables by combining iteration, transformation, and optional filtering into a single line. The structure follows:
new_list = [transformed_element for element in source_iterable if optional_filter]
Without list comprehensions, filtering even values from a list requires verbose loop logic:
original_values = [0, 1, 2, 3, 4, 5]
filtered_evens = []
for num in original_values:
if num % 2 == 0:
filtered_evens.append(num)
print(filtered_evens) # Output: [0, 2, 4]
With list comprehensions, this logic condenses neatly:
>>> original_values = [0, 1, 2, 3, 4, 5]
>>> filtered_evens = [num for num in original_values if num % 2 == 0]
>>> filtered_evens
[0, 2, 4]
List comprehensions also support parallel iteration over multiple sequences using zip(). For example, combining integers and single characters:
nums = [1, 2, 3, 4, 5]
chars = ['x', 'y', 'z', 'w', 'v']
paired_output = [f'{char}{num}' for char, num in zip(chars, nums)]
print(paired_output) # Output: ['x1', 'y2', 'z3', 'w4', 'v5']
Dictionary Comprehensions
Dictionary comprehensions mirror list comprehensions but use curly braces {} and require key-value pairs separated by colons. The structure is:
new_dict = {transformed_key: transformed_value for key, value in source_dict.items() if optional_filter}
Consider a scenario where we extract students with perfect math scores from a nested grade dictionary:
student_grades = {
"Luna": {"history": 85, "math": 98, "art": 91},
"Ethan": {"history": 90, "math": 100, "art": 82},
"Mia": {"history": 79, "math": 100, "art": 95}
}
perfect_math = {name: grades for name, grades in student_grades.items() if grades["math"] == 100}
print(perfect_math)
# Output: {'Ethan': {'history': 90, 'math': 100, 'art': 82}, 'Mia': {'history': 79, 'math': 100, 'art': 95}}
Set Comprehensions
Set comprehensions use curly braces {} like dictionary comprehensions but contain only single elements, automatically handling deduplication. The basic structure:
new_set = {transformed_element for element in source_iterable if optional_filter}
A common use case is removing duplicates from a list:
>>> raw_values = [2, 2, 4, 4, 6, 6, 8]
>>> unique_vals = {val for val in raw_values}
>>> unique_vals
{2, 4, 6, 8}
Generator Comprehensions
Generator comprehensions look nearly identical to list comprehensions but use parentheses (). Unlike list comprehensions, they produce a generator object that yields elements one at a time instead of storing the entire sequence in memory, making them ideal for large datasets.
>>> original_values = [0, 1, 2, 3, 4, 5]
>>> even_generator = (num for num in original_values if num % 2 == 0)
>>> even_generator
<generator object <genexpr> at 0x10a1b2d60>
>>> next(even_generator)
0
>>> next(even_generator)
2