Lists are a basic building block for a developer in any language. Python is no different. However at first, list comprehension can sometimes seem confusing. Since it is not an available feature in all languages, it may also be a concept that is completely unfamiliar. Some popular languages that include list comprehension are JavaScript, Perl 6, C# and of course, Python.
List Comprehension in Python
Today, we’ll take a look at exactly how list comprehension works in Python. In this post, we’ll cover the following concepts:
- What is List Comprehension?
- What are the advantages of List Comprehension?
- What are some ways that List Comprehension can be used?
- What are some common examples of List Comprehension?
- When should List Comprehension be used, as opposed to other methods?
What is List Comprehension?
At its most basic level, list comprehension is a syntactic construct for creating lists from existing lists. This definition describes some of the uses that we’ll talk about later. If we don’t need to make a new list, but simply print results from an existing list, then list comprehension wouldn’t really be helpful to us. In Python, there are many ways to create lists.
If we wanted to create an empty list, we could declare it as such:
listA = []
Or, if we wanted to create a list with values in it, we could do it this way:
listB = [1,2,3,4]
If we wanted to create a list of 10 items, each item having the same value, we could also do the following:
# which would give us the following output:
>>1,1,1,1,1,1,1,1,1,1
Another way to create a list would be looping through an existing list, and appending or inserting data from the first list into a second list.
This might look like the following:
listB = [1,2,3,4,5,6]
fornumber in listB:
if number % 2 == 0:
listA.append(number)
Here, we are looping over listB, and if the current value in the list is even, we append it to listA. This is a case where we might use list comprehension. Let’s first consider the syntax of a standard loop like the one above, and compare that with the syntax for the same concept, but using list comprehension instead.
Syntax of a for loop:
Which is equivalent to this list comprehension:
[ expression for item in list if conditional ]
An expression is a fancy way of saying “output”. So in each of these cases the output is the result of executing some code. In our previous example, the output was appending something to a new list.
Also in both a traditional for loop and in list comprehension, we have the list to be iterated over, the item or iterable in the list, and a conditional statement.
Let’s take a closer look at the syntax of a for loop:
In a Python for loop, we would start the loop, have a conditional statement if necessary, followed by an execution of a block of code. In the above example, we can see how this would work, along with the expected output.
Here’s how we could rewrite this same piece of code with list comprehension:
Here, we can see that all of the same building blocks that we used in our for loop still exist in the list comprehension, albeit in a slightly different order.
Advantages of List Comprehension
This brings us to the next topic, the advantages of list comprehension. The above example, while slightly less cumbersome than the for loop, can still be consolidated into an even more concise format. One of the big advantages of list comprehension is that they allow developers to write less code that is often easier to understand.
Here’s how we could further simplify the above example:
Here we’ve taken our original three lines of code, and reduced it to an easy to read single line of code.
Other advantages:
List comprehension is usually faster, but only if it is actually being used to create a new list. If you notice, in the first example, we included the append method in the for loop, but when we completely consolidated our code, we left the append method out of the list comprehension completely. This is because in Python, we don’t need to load the append attribute off of the list and call it as a function. Instead, in a comprehension, a specialized LIST_APPEND bytecode is generated for a fast append onto the result list.
In the first example, the append() method would be necessarily called in every iteration of the loop. This means, if our loop had been one million iterations, the append() method would have been called one million times, making it noticeably slower than list comprehension.
How can list comprehension be used?
The above example could be called a filter function. We are taking an existing list, and filtering that list to make a new list. In this case it was to get either the odd or even numbers from a sequence, but the same could be done with other filtering scenarios like generating the fibonacci sequence.
Here are some other examples of ways we might use list comprehension:
- To filter an existing list.
- To generate a list of data
- Flattening a multidimensional list
We’ve already seen an example of how we might use list comprehension to filter the results of one list into a new list. Now let’s look at how we might use it to generate a list of data.
In a previous post, we looked at how we could use python to determine the compound interest on a loan.
Below, we’ll generate a list of dicts, each dict containing a loan with a different principal value, and final value. The final value in each dict will be determined by the initial value we give it, based on the formula for determining compound interest. This formula and dict generation will be stored in it’s own function, but in the loop, and list comprehension, we’ll call the function based on a range of numbers in the loop.
Let’s take a look at the for loop first:
Each time the for loop iterates over a number in the range we’ve set, it then calls the newDict function, and appends the result of that function to our newList. If we print the results, we should see a list of dicts, each containing a unique set of data.
If we rewrite this using list comprehension, we can again avoid using the append method, saving valuable resources on such a large data set.
Here’s what that would look like:
Finally, let’s take a look at how we might use list comprehension to flatten a multidimensional list in Python.
If we were to do this with a for loop, it would likely need to be a nested loop, similar to the following:
We can see here how this might come in handy, if we had a list of lists of names, and needed them quickly flattened into a single list.
Rewriting this code using list comprehension would look like the following:
When should list comprehension be used?
We talked earlier about one of the advantages of list comprehension. This advantage was that we didn’t need to use the append() method to create a new list. List comprehension is great for creating new lists for many reasons:
- The code is more concise
- The code is generally more readable
- The code, in most cases, will run faster
However, this may not always be what is needed. In some cases, we may simply need to print the results of a list as they are iterated over. In which case, list comprehension provides not obvious advantage. In fact, we would end up creating an unneeded list at that point, using unnecessary memory. When deciding whether or not list comprehension would be a better choice than a loop, we can simply ask ourselves, “am I creating a new list?”
If the answer is “yes”, then list comprehension is probably the preferred method in doing so. If not, than a good old fashioned for loop is probably better.