List Comprehensions
Python includes a compact syntax for creating lists called list comprehensions. A new list is derived from iterating over another iterable or sequence. The Python docs demonstrate a simple use case squaring numbers over a specified range. We'll use range(1, 11)
, which creates a sequence of integers from 1 to 10 (not 1 to 11 as you might expect).
squares = [x**2 for x in range(1, 11)]
# Output: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
The list comprehension creates a new list from the following logic: square the value of x for every digit in a range of integers from 1 to 10. For comparison, a traditional for loop requires two extra lines of code to achieve the same result.
squares = []
for x in range(1, 11):
squares.append(x**2)
# Output: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Two extra lines is not a big deal by itself. However, visual noise adds up in a larger program and makes the code more difficult to read and understand.
Alternatively, the built-in map function can be used in conjunction with a lambda, but that too is not as easily readable as a list comprehension.
squares = list(map(lambda x: x**2, range(1, 11)))
# Output: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
The difference is even more noticeable when a condition needs to be applied. Such as only square even numbers. The map solution uses filter (another built-in function) to exclude odd numbers. Whereas a list comprehension applies an if conditional.
map_squares = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, range(1, 11))))
# Output: [4, 16, 36, 64, 100]
lc_squares = [x**2 for x in range(1, 11) if x % 2 == 0]
# Output: [4, 16, 36, 64, 100]
Python code should be Pythonic, a coding style that favors clear and precise statements. The list comprehension is straightforward compared to map and filter in this example.
Furthermore, the comprehension syntax used to create lists can also be used to create dictionaries or sets.
squares = {x: x**2 for x in range(1, 11) if x % 2 == 0}
# Output: {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
List comprehensions are also capable of iterating over multiple loops. For example, calculate the average grades from three sets of student grades from three exams. A normal for loop is quite verbose and harder to follow than the list comprehension in the snippet below.
All in all, list comprehensions are an excellent way to improve the readability of Python code with concise logic. As long as the expression isn't excessively long or complex.