4.5 List Comprehensions

List comprehensions in Python provide a concise and efficient way to create lists by applying an expression to each item in an iterable (such as a list, tuple, or range). They are particularly useful for transforming, filtering, or generating lists in a single line of code, making your Python programs more readable and efficient.

In this section, we’ll explore how list comprehensions work, including basic and advanced examples, as well as practical use cases.


4.5.1 Basic List Comprehension Syntax

A list comprehension consists of square brackets containing an expression followed by a for clause, optionally followed by if statements to filter items.

Syntax:

new_list = [expression for item in iterable if condition]
  • expression: The value or transformation applied to each item.
  • item: The variable that takes each value from the iterable.
  • iterable: The sequence to iterate over (e.g., list, tuple, string, range).
  • condition (optional): A filtering condition that determines whether to include the item in the new list.

4.5.2 Examples of List Comprehensions

Example 1: Basic List Comprehension

Create a list of squares of numbers from 1 to 5.

squares = [x**2 for x in range(1, 6)]
print(squares)  # Output: [1, 4, 9, 16, 25]

In this example:

  • The expression is x**2 (the square of x).
  • The iterable is range(1, 6).

Example 2: List Comprehension with Filtering

Create a list of even numbers from 1 to 10.

evens = [x for x in range(1, 11) if x % 2 == 0]
print(evens)  # Output: [2, 4, 6, 8, 10]

In this case, the if condition filters out the numbers that are not even.

Example 3: List Comprehension with Strings

Create a list of the first letters of each word in a list of strings.

words = ["apple", "banana", "cherry"]
first_letters = [word[0] for word in words]
print(first_letters)  # Output: ['a', 'b', 'c']

Here, word[0] extracts the first letter of each string in the list words.


4.5.3 List Comprehensions with Multiple for Loops

You can use multiple for loops in a list comprehension to create lists based on combinations of elements from multiple iterables.

Example 1: Cartesian Product

Create a list of pairs from two different lists.

list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
pairs = [(x, y) for x in list1 for y in list2]
print(pairs)  # Output: [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]

This example generates all possible pairs between the elements of list1 and list2.


4.5.4 Nested List Comprehensions

List comprehensions can also be nested, meaning you can include one list comprehension inside another. This is useful when working with multi-dimensional data, such as lists of lists.

Example: Flatten a Nested List

Flatten a 2D list (list of lists) into a single list.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat_list = [num for row in matrix for num in row]
print(flat_list)  # Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In this example:

  • The outer loop for row in matrix iterates over each row.
  • The inner loop for num in row iterates over each element in the current row, flattening the matrix.

4.5.5 List Comprehensions with Conditional Expressions

You can include conditional expressions inside the comprehension to create lists based on conditions. This is often used to apply transformations based on conditions.

Example: Apply Conditional Expression in List Comprehension

Create a list where even numbers are squared and odd numbers remain unchanged.

numbers = [1, 2, 3, 4, 5]
modified = [x**2 if x % 2 == 0 else x for x in numbers]
print(modified)  # Output: [1, 4, 3, 16, 5]

In this case:

  • x**2 if x % 2 == 0 else x squares the number if it is even and leaves it unchanged if it is odd.

4.5.6 Practical Use Cases for List Comprehensions

Example 1: Filtering and Transforming Data

Generate a list of lengths of words that are longer than 3 characters.

words = ["cat", "elephant", "dog", "mouse"]
long_word_lengths = [len(word) for word in words if len(word) > 3]
print(long_word_lengths)  # Output: [8, 5]

Example 2: Reading from a File

Suppose you have a file and want to extract lines that contain a certain keyword.

with open("file.txt") as f:
    keyword_lines = [line.strip() for line in f if "keyword" in line]

This reads the file, filters out lines that don’t contain the keyword, and removes any leading or trailing whitespace.

Example 3: Generating a Matrix

Generate a 3x3 matrix using a list comprehension.

matrix = [[i + j for j in range(3)] for i in range(3)]
print(matrix)  # Output: [[0, 1, 2], [1, 2, 3], [2, 3, 4]]

4.5.7 List Comprehensions vs. Loops

List comprehensions can often replace traditional for loops when generating or transforming lists. They are shorter and more readable but can be harder to understand if too complex. Use list comprehensions when:

  • The task involves applying a transformation or filtering.
  • Readability is maintained.

However, avoid using them for very complex logic where traditional loops and function calls might be clearer.

Example: Traditional Loop vs. List Comprehension

Traditional loop:

squares = []
for x in range(1, 6):
    squares.append(x**2)

Equivalent list comprehension:

squares = [x**2 for x in range(1, 6)]

Both methods produce the same result, but the list comprehension is shorter and more concise.


4.5.8 Summary

  • List comprehensions provide a concise way to create lists by applying an expression to each element in an iterable.
  • They can include filtering conditions to exclude certain items from the resulting list.
  • List comprehensions can handle multiple for loops, nested lists, and conditional expressions, making them powerful and flexible.
  • They are best used when the logic is simple and the goal is to transform or filter a list in a readable and efficient way.

Mastering list comprehensions will help you write more concise, readable, and efficient Python code, especially when working with data processing or generating new lists based on existing data.