Comprehensions

The Importance of Comprehensions in Python


Python’s comprehensions (list, set, and dictionary) are concise, elegant one-liners for creating collections. They offer several key advantages:
Comprehensions often express the desired collection in a more natural way compared to traditional loops.
They condense multiple lines of iterative code into a single, focused expression.
In many cases, comprehensions can be faster than equivalent loop-based solutions, especially for simple operations.
They encourage a functional programming style, where the focus is on transformations rather than explicit iteration mechanics.
List Comprehensions

Without Comprehension (Traditional Loop)

squares = []
for x in range(10):
squares.append(x**2)

print(squares)

# Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

With List Comprehension

squares_comp = [x**2 for x in range(10)]
print(squares_comp) # Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
The list comprehension is more concise, expressing the desired operation (squaring) directly without the need for an explicit loop or append statement.
List comprehensions create new lists by applying an expression to each item in an iterable (like a list, tuple, or range), optionally filtering items based on a condition.

Basic List Comprehensions

Square the numbers from 0 to 9

squares = [x2 for x in range(10)] print(squares)

# Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

This comprehension iterates over the numbers produced by range(10) (0 through 9). For each number x, it calculates x2 (x squared) and includes the result in the new list squares.

Convert strings in a list to uppercase

words = [“hello”, “world”, “python”]
uppercase_words = [word.upper() for word in words]
print(uppercase_words)

# Output: [‘HELLO’, ‘WORLD’, ‘PYTHON’]
This comprehension iterates over the strings in the words list. For each word, it calls the upper() method to convert it to uppercase and includes the result in the uppercase_words list.

List Comprehensions with Conditions

Get even numbers from a list

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
even_numbers = [num for num in numbers if num % 2 == 0]
print(even_numbers)

# Output: [2, 4, 6, 8]
This comprehension iterates through numbers. It includes a number num in the even_numbers list only if the condition num % 2 == 0 (num is divisible by 2) is True.

Select only the strings with length greater than 3

words = [‘cat’, ‘hello’, ‘world’,’to’, ‘python’,’dog’]
long_words = [word for word in words if len(word) > 3]
print(long_words)

# Output: [‘hello’, ‘world’, ‘python’]
This comprehension filters the words list, keeping only those strings word where the length (len(word)) is greater than 3.

Nested List Comprehensions

Create a matrix (list of lists)

matrix = [[row, col] for row in range(3) for col in range(4)]
print(matrix)

Output: [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3]]

This comprehension has nested loops. The outer loop (for row in range(3)) iterates over the rows, and the inner loop (for col in range(4)) iterates over the columns. For each combination of row and col, it creates a list [row, col] and adds it to the matrix.

Set Comprehensions

Without Comprehension (Traditional Loop)

unique_chars = set()
for char in “hello world”:
unique_chars.add(char)

print(unique_chars)

# Output: {‘l’, ‘d’, ‘o’, ‘e’, ‘r’, ‘w’, ‘h’}

With Set Comprehension

unique_chars_comp = {char for char in “hello world”}
print(unique_chars_comp)

# Output: {‘l’, ‘d’, ‘o’, ‘e’, ‘r’, ‘w’, ‘h’}
The set comprehension eliminates the need for the separate set() initialization and the add() method within the loop.
Set comprehensions are similar to list comprehensions, but they create sets (unordered collections with unique elements).

Get unique letters from a string

text = “hello world”
unique_letters = {char for char in text}
print(unique_letters)

# Output: {‘l’, ‘d’, ‘o’, ‘e’, ‘r’, ‘w’, ‘h’}
This comprehension iterates over each char in the string text. Since it’s a set comprehension, duplicates are automatically eliminated, resulting in a set containing only the unique letters.
You can use conditions and nested for loops within set comprehensions just like with list comprehensions.

Dictionary Comprehensions

Without Comprehension (Traditional Loop)

squares_dict = {}
for num in range(1, 6):
squares_dict[num] = num ** 2

print(squares_dict)

# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

With Dictionary Comprehension

squares_dict_comp = {num: num ** 2 for num in range(1, 6)}
print(squares_dict_comp)

# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
In the traditional loop approach, an empty dictionary squares_dict is initialized, and a for loop iterates through numbers from 1 to 5. Within the loop, the square of each number is calculated (num ** 2) and assigned as the value for the key num in the dictionary. In contrast, the dictionary comprehension achieves the same result in a single line by directly expressing the transformation: it iterates through the numbers and concisely inserts the key-value pairs (num: num** 2) into the new dictionary squares_dict_comp.
Dictionary comprehensions create dictionaries by mapping keys to values based on an expression.

Square the keys and values

numbers = {1: 1, 2: 4, 3: 9}
squared_dict = {k2: v2 for k, v in numbers.items()}
print(squared_dict)

# Output: {1: 1, 4: 16, 9: 81}
This comprehension iterates over the key-value pairs (k, v) in the numbers dictionary. For each pair, it squares both the key and the value and creates a new key-value pair in the squared_dict.

Create a dictionary from two lists

keys = [“a”, “b”, “c”]
values = [1, 2, 3]
my_dict = {k: v for k, v in zip(keys, values)}
print(my_dict)

# Output: {‘a’: 1, ‘b’: 2, ‘c’: 3}
The zip function pairs up the elements from the keys and values lists. The comprehension then creates a dictionary where each key from keys is mapped to its corresponding value from values.

Combining Conditions and Nested Loops

Map words to their lengths, only for words longer than 3 characters

word_lengths = {word: len(word) for word in words if len(word) > 3}
print(word_lengths)

# Output: {‘hello’: 5, ‘world’: 5, ‘python’: 6}
This comprehension iterates over each word in the words list. If a word’s length is greater than 3, the word is used as the key, and its length (len(word)) is used as the value in the resulting word_lengths dictionary.