Python Basics: List Comprehensions
After reading this article you’ll learn:
- What are the list comprehensions in Python
- What are set comprehensions and dictionary comprehensions
What are List Comprehensions?
List comprehensions provide us with a simple way to create a list based on some iterable. During the creation, elements from the iterable can be conditionally included in the new list and transformed as needed.
An iterable is something you can loop over. If you want a more detailed explanation you can read my previous blog post.
The components of a list comprehension are:
- Output Expression (Optional)
- Iterable
- Iterator variable which represents the members of the iterable
Example
Output:
[1, 4, 9, 16, 25]
We can also create more advanced list comprehensions which include a conditional statement on the iterable.
Example
Output:
[9, 16, 25]
List Comprehensions vs loops
The list comprehensions are more efficient both computationally and in terms of coding space and time than a for
loop. Typically, they are written in a single line of code.
Let’s see how much more space we’ll need to get the same result from the last example using a for
loop.
We can clearly see that the list comprehension above was much easier to write. However, keep in mind that:
Every list comprehension can be rewritten as a for loop, but not every for loop can be rewritten as a list comprehension.
Source: https://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/
What about the computational speed? We can use the timeit
library to compare the speed of a for
loop vs the speed of a list comprehension. We can also pass the number of executions using the number
argument. We’ll set this argument to 1 million.
Output:
6.255051373276501
3.7140220287915326
I’ve run this on my machine, so you can get different results. However, the list comprehension implementation will be faster in all cases.
List Comprehensions vs map and filter
List comprehensions are a concise notation borrowed from the functional programming language Haskell. We can think of them like a syntactic sugar for the filter
and map
functions.
We have seen that list comprehensions can be a good alternative to for
loops because they are more compact and faster.
Lambda Functions
Lambda functions are small anonymous functions. They can have any number of arguments but can have only one expression.
Mostly, the lambda functions are passed as parameters to functions which expect a function object as one of their parameters like map
and filter
.
Map Function
The map function returns an iterator that applies a function to every item of iterable, yielding the results. Let’s compare it with a list comprehension.
Output:
[1, 4, 9, 16, 25]
[1, 4, 9, 16, 25]
Filter Function
The filter function constructs an iterator from elements of iterable for which the passed function returns true. Again, let’s compare the filter function versus the list comprehensions.
Output:
[2, 4]
[2, 4]
More Complex List Comprehensions
Additionally, when we’re creating a list comprehension we can have many conditional statements on the iterable.
Output:
[6, 18]
Moreover, we can also have an if-else clause on the output expression.
Output:
['small', 'big']
Readability
We can see that some list comprehensions can be very complex and it’s hard to read them. Python allows line breaks between brackets and braces. We can use this to make our complex comprehension more readable.
For example, we can our last transform example to this:
Output:
['small', 'big']
However, be careful with the list comprehensions, in some cases is better to use for
loops. If your code is not readable, it’s better to use for loops.
Nested For Loops
In some cases, we need nested for
loops to complete some task. In this cases, we can also use a list comprehension to achieve the same result.
Imagine that we have a matrix and we want to flatten it. We can do this easily with two for
loops like this:
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
We can achieve the same result using a list comprehension.
Tip: the order of the for clauses remain the same as in the original for loops.
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Nested List Comprehensions
In other cases, we may need to create a matrix. We can do that with nested list comprehensions. This sound a little bit crazy, but the concept is simple.
One list comprehension returns a list, right? So, if we place a list comprehension in the output expression of another list comprehension, we’ll get a matrix as result.
Output:
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
The
range
type represents an immutable sequence of numbers and is commonly used for looping a specific number of times infor
loops
Source: https://docs.python.org/3/library/stdtypes.html#ranges
Other Comprehensions
In Python, we have also dictionary comprehensions and set comprehensions. All the principles we saw are the same for these comprehensions, too. We just have to know some very little details to create a dictionary or set comprehensions.
Dictionary Comprehensions
To create a dictionary comprehension we just need to change the brackets []
to curly braces {}
. Additionally, in the output expression, we need to separate key and value by a colon :
.
Output:
{'beer': 2.0, 'fish': 5.0, 'apple': 1.0}
Set Comprehensions
To create a set comprehension we only need to change the brackets []
to curly braces {}
.
Output:
{0, 1, 100, 144, 400, 900}
Generator expressions
Here, I just want to mention that Python also has something called generator expressions. They are very similar to the list comprehensions. The difference is that they use round brackets ().
Also, they don’t store the list in memory. They use the lazy evaluation technique.
List comprehensions aren’t useful if you’re working with iterators that return an infinite stream or a very large amount of data. Generator expressions are preferable in these situations.
Source: https://docs.python.org/3/howto/functional.html
If you want to learn more about generator expressions you check my previous blog post.
Summary
- List comprehensions provide us with a simple way to create a list based on some iterable.
- The comprehensions are more efficient than using a for a loop.
- We can use conditional statements in the comprehensions.
- Comprehensions are a good alternative to the built-in
map
andfilter
functions. - We can have nested comprehensions.
- In Python, we have also dictionary comprehensions and set comprehensions.
- Generator expressions are preferable when we work with an infinite stream of a very large amount of data.
Resources
- https://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/
- https://www.datacamp.com/community/tutorials/python-list-comprehension
- https://www.w3schools.com/python/python_lambda.asp
- https://talkai.blog/2018/08/29/pythonic-better-if-list-comprehension-else-map-and-filter/
- https://docs.python.org/3/library/functions.html
https://docs.python.org/3/howto/functional.html
Other Blog Posts by Me
You can also check my previous blog posts.
- Jupyter Notebook Shortcuts
- Python Basics for Data Science
- Python Basics: Iteration, Iterables, Iterators, and Looping
- Data Science with Python: Intro to Data Visualization with Matplotlib
- Data Science with Python: Intro to Loading, Subsetting, and Filtering Data with pandas
- Introduction to Natural Language Processing for Text
Newsletter
If you want to be notified when I post a new blog post you can subscribe to my newsletter.
Here is my LinkedIn profile in case you want to connect with me. I’ll be happy to be connected with you.
Final Words
Thank you for the read. I hope that you have enjoyed the article. If you like it, please hold the clap button and share it with your friends. I’ll be happy to hear your feedback. If you have some questions, feel free to ask them. 😉