How to Use Python List Comprehensions (And When Not to Use Them)
You may have heard of Python’s list comprehension. Maybe it’s even something you’ve used without really understanding. Now is the time to learn, as we cover everything you need to know about list comprehension in Python.
Before getting started, it’s worth refreshing yourself on how arrays and lists work in Python and how to use Python dictionaries.
What Is Python List Comprehension?
List comprehension sounds complex but it really isn’t. In Python, it’s simply a quick way to filter or refine a list based on some criteria.
It saves you having to write several lines of code (especially if you’re in a loop already), and it keeps the readability of your code neat.
Be careful, however, as list comprehension is not always the answer. It’s easy to get carried away and write complex comprehensions that are tough to read. Sometimes writing more code is better, especially if it helps readability. Stick to simple tasks, and keep code to a single responsibility.
How to Use List Comprehensions in Python
Note: These examples all use Python 3.6. If you’re not sure of the differences between Python 3 and Python 2, then make sure you read our Python FAQ, where we cover this question and more.
Consider this bit of code that copies an array and turns each letter in that array into an uppercase. It does so by looping through each item in the array:
letters = ['a', 'b', 'c', 'd']
print(letters)
upper_letters = []
for letter in letters:
result = letter.upper()
upper_letters.append(result)
print(upper_letters)
Now here’s the same exact logic, except done in a single line of code using a basic Python list comprehension:
letters = ['a', 'b', 'c', 'd']
print(letters)
upper_letters = [x.upper() for x in letters]
print(upper_letters)
As you can see, the result is exactly the same, but the process involves significantly more code without list comprehension.
Let’s break this simple example down.
This example creates a list called letters. This stores the lowercase letters “a”, “b”, “c”, and “d”. Supposing you want all these list elements to be uppercase? Well, without list comprehension, you have to create a new list to store the result (called upper_letters), loop over every element in the letters list, convert each letter (and store it in result—optional but good practice), and then append the uppercase letter to the new list. What a lot of work!
The list comprehension here is almost exactly equivalent to the loop alternative. It effectively says “for every letter in the letters list, convert them to uppercase, and return the result as a new list.”
List comprehension can only work on lists, and must return a new list. Let’s dig deeper.
There are three parts to a list comprehension (we’ll cover the third part below). List comprehensions must start and end with square brackets ([ and ]). This is how it was designed, and lets Python know that you’ll be working with a list.
Inside the square brackets, you need to start with the result. This is what you want to do with each list element.
In the example above, the following code converts each element (referenced by the variable name x) to upper case by using the upper() method, which is part of the Python core library:
[x.upper() # will not run, only half the comprehension at this point
Next, you need to tell Python which list to work on, and assign each individual element to a variable. This is exactly the same as the for loop in the long winded example:
for x in letters
Every time the loop goes over the list, the value of x will change to whatever the current element is. It will start off as “a”, and then “b”, and so on.
If you put it all together (and assign it to a variable called upper_letters), you’ll be done:
upper_letters = [x.upper() for x in letters]
Now, upper_letters will contain a list of uppercase letters, starting at “A”, and then “B” and so on.
The Third Part of List Comprehension in Python
As we mentioned above, there’s a third part to list comprehension.
Once you’ve done the two steps above, you can include an optional condition. This is like using an if statement to say “make me a new list, based on this old list, but only include elements which meet my criteria”.
Here’s what it looks like:
ages = [1, 34, 5, 7, 3, 57, 356]
print(ages)
old_ages = [x for x in ages if x > 10]
print(old_ages)
This example uses a new list called ages. The old_ages list is assembled using a list comprehension. The if condition on the end means that only list elements which meet the criteria are inserted into the new list. In this example, any ages greater than ten are allowed.
When Not to Use Python List Comprehensions
List comprehension is amazing once you’ve got the hang of it, but it’s not useful in every circumstance. You probably shouldn’t use it when you need more than one condition:
old_ages = [x for x in ages if x > 10 and x < 100 and x is not None]
This code works, but it’s starting to get long and confusing. Similarly, anything more than a simple function call may not work. In this example, you’ll get an error:
letters = ['a', 'b', 'c', 'd', 2]
print(letters)
upper_letters = [x.upper() for x in letters]
print(upper_letters)
This is perfectly valid code, but as you cannot uppercase a number, it won’t work. This is one case when the longer loop is actually preferable, as you’ll be able to do some exception handling:
letters = ['a', 'b', 'c', 'd', 1]
print(letters)
upper_letters = []
for letter in letters:
try:
result = letter.upper()
upper_letters.append(result)
except AttributeError:
pass # do nothing
print(upper_letters)
Start Putting Python List Comprehensions to Use
Now that you know just how easy list comprehension is in Python, there’s no reason not to be using it. Just remember to keep it simple, and consider the readability above all else.
Maybe you’ll control an Arduino with Python, or what about a DIY Python network security camera?
Read the full article: How to Use Python List Comprehensions (And When Not to Use Them)