List Comprehensions
Learn how a list comprehension makes code more readable and concise.
Introduction
A list is one of the container sequences offered by Python’s standard library, as it holds the reference to the objects it contains. It is a mutable sequence.
✏️ Note: To refresh the concept of the list, click here to get a quick overview of how to make a new list.
Assuming you know the basics of the list, let us scrutinize list comprehension which is an underused but wieldy and concise method to make a list.
It consists of brackets containing an expression followed by a for
clause, then zero, or more for
or if
clauses. The result is a new list resulting from evaluating the expression in the context of the for
and if
clauses that follow it.
Explanation
Testing the readability
Let’s see how list comprehensions make a program more readable and concise. Below is a program for implementing a list without using a list comprehension:
letters = 'Python'alphabets = [] # Creating a new listfor letter in letters:alphabets.append(letter) # Adding elements from letters to alphabetsprint(alphabets)
In the code above, we create an initial blank list, alphabets
, at line 2. Then, we fill it with a for
loop at line 5 using letters
list. Now, let’s exercise list comprehension for the same purpose and see how the program’s size decreases, and the program becomes more readable.
letters = 'Python'alphabets = [letter for letter in letters] # Adding elements from letters to alphabetsprint(alphabets)
Now, you see how a list comprehension works like a charm! We created and filled alphabets
in just one line using a list comprehension, unlike the previous program (without a list comprehension) that needed three lines to do the same thing. The later program gives a sense that a Python expert wrote it.
No leaky variables in Python 3
If you’ve ever programmed in Python 2, you may have noticed that a variable leaks its value due to the surrounding scope when using a list comprehension. Run the following program to observe the issue.
letters = 'Python'alphabets = [letters for letters in letters] # Scope of letters is surrounding scopeprint(letters)
You see, when we print the letters
(at line 4), instead of getting Python, we just get n of Python. This is because the scope of the first occurrence of letters
in letters for letters in letters
(at line 2) is the surrounding scope, which means it’s referring to the letters
at line 1.
Here comes Python 3 to the rescue. It solves the problem by assigning the first occurrence of letters
in letters for letters in letters
with a local scope instead of the surrounding scope. Run the following program and witness the magic!
letters = 'Python'alphabets = [letters for letters in letters] # Scope of letters is local scopeprint(letters)
Python 3 saves the day by preserving the value of letters
. Here, the scope of the first occurrence of letters
in letters for letters in letters
(at line 2) is local scope, which means it’s not pointing to the letters
at line 1.
Filtering with list comprehension
We can filter values from a list using for
loop or a filter method. But it requires a few lines of computation. Do you want to do it in a single line of code? If yes, then use a list comprehension.
Run the following program to see how a list comprehension can filter a list.
numbers = [1,2,3,4,5,6,7,8,9,10]even = [number for number in numbers if number %2 ==0] # Filtering even numbersprint(even)
See how the list comprehension does wonders! It picks every number from numbers
using the for
keyword and filter it using an if
condition, all in one single line.
Enriched iterations with list comprehension #
The list comprehension can also replace the nested for loops for the sake of efficiency. Let’s compare both of them. Below is a program for implementing enriched iterations without using a list comprehension.
even = [2,4,6,8,10]odd = [1,3,5,7,9]pair = []for number1 in even: # Taking every number from evenfor number2 in odd: # Taking every number from oddpair.append((number1, number2)) # Pairing every number from even with every number from oddprint(pair)
In the code above, you can see that an outer-loop (at line 5), takes a value from even
turn by turn, and an inner-loop (at line 6), takes value from odd
turn by turn. The numbers are then paired in the form of a tuple in the list pair
. As a result, pair
holds the cartesian product of the even
and odd
lists.
❌ Note: A tuple (pair) shouldn’t be generated with elements from one list!
Now, let’s use list comprehension for the same purpose, and see how the program’s size decreases, and the program becomes more readable.
even = [2,4,6,8,10]odd = [1,3,5,7,9]# Pairing every number from even with every number from oddpair = [(number1,number2) for number1 in even for number2 in odd]print(pair)
Once again, list comprehension works like a charm! We created and filled pairs
in just one line (see line 5) using a list comprehension, unlike the previous program (without a list comprehension) that required four lines to do the same thing. The later program gives a sense that a Python expert wrote it.
Having some know-how about these little programming techniques makes a huge difference.