Python List and Dictionary Comprehensions
Python is one of my favourite languages when it comes to producing a solution to some programming problem quickly and in a relatively neat manner. One of the tools that Python provides to help create neat solutions is Comprehensions, more specifically List and Dictionary Comprehensions.
Python is one of my favourite languages when it comes to producing a solution to some programming problem quickly and in a relatively neat manner. One of the tools that Python provides to help create neat solutions is Comprehensions, more specifically List and Dictionary Comprehensions.
A Comprehension is an elegant way of constructing a list or dictionary in Python. It allows us to loop through existing data and filter it to create a list or dictionary, or we can even loop through a sequence that we generate and make a list or dictionary from that sequence.
Video
I have created a video on this blog post for you to watch if you prefer:
Lists vs. Dictionaries
Before we dive into the specifics of List and Dictionary Comprehensions, we first need to know the difference between an actual List and a Dictionary. If you already know, you’re welcome to skip this section.
Lists
In Python, lists are an array of objects that are stored in sequential order. They are represented using []
(square brackets). Unlike many other languages, a list can contain a mixture of different data types.
The following is an example of a Python list:
[123, "string", True, 'hi']
Dictionaries
Dictionaries are similar to lists in that they store an array of objects, but these objects are accessed using keys and the object we are accessing is called the value. In Python, these are represented using {}
(curly braces).
The following is an example of a Python dictionary:
{"name" : "Ivan", "surname" : "Kahl", "age" : 19}
List Comprehensions
A list comprehension processes data to return a list of values afterwards.
Syntax of a List Comprehension
[some_function(x) for x in original_list if certain_condition]
The first thing to notice is that because this is a list comprehension, it is surrounded in []
(square brackets). Python recognises a list and then, by looking at the syntax inside the square brackets, is able to determine that this is a list comprehension.
The first thing that we put inside these square brackets is what we want to return after processing each data item (represented by x
in this case). In this case, we are performing some_function
on x
and then returning it.
Next, we have our for loop where we loop through each item in another iterable (this could be an existing list or a sequence generated with the range
function). Here we loop through original_list
and assign each item in original_list
to x
, which we are processing in the first part of the comprehension. This variable can be called anything though, it doesn’t have to be x
.
The last part of the list comprehension is completely optional. It allows us to filter values based on a certain condition. This can be any conditional expression and can include x
(the current data item you are processing). If the condition evaluates to True
, the data item is processed and inserted into the new list which is returned afterwards, otherwise it is skipped.
This whole list comprehension returns a new list containing the new values that have been processed.
List Comprehension Examples
Example 1: Square all numbers in a list
In our first example, let’s just square all the numbers in a list using a list comprehension. So we will be processing each original number (represented by x
in this case) by squaring it (x * x
). No conditional statement is necessary because we are simply squaring all the numbers regardless of any conditions.
Our comprehension would look as follows:
squared_n = [x * x for x in n]
Let’s give it a test run:
n = [1, 6, 4, 2, 9, 15, 5]
squared_n = [x * x for x in n]
print squared_n
# Output: [1, 36, 16, 4, 81, 225, 25]
As you can see, it produced a new list where each item was the square of the original item in the original list n
.
Example 2: Return only even numbers
In this next example, we will be given a list of numbers. We must go through and filter this list so that we only return the even numbers in the original list. In this case, no processing is required because we want the original data item in the returned list. We will however need a conditional statement that will return True when our data item (x
) is even (i.e. x % 2 == 0
).
Our list comprehension will look as follows:
even_n = [x for x in n if x % 2 == 0]
Let’s test out the comprehension:
n = [1, 7, 4, 5, 8, 12, 11]
even_n = [x for x in x if x % 2 == 0]
print even_n
# Output: [4, 8, 12]
As you can see, the list comprehension only returned the even numbers in the new list.
Example 3: Return all the odd numbers doubled
Now we have to find all the odd numbers in the list and double them before returning them in a new list. This means we will have to filter out all the even numbers using a conditional (x % 2 != 0
) and then double the remaining numbers (2 * x
).
Here is our list comprehension:
doubled_odd_n = [2 * x for x in n if x % 2 != 0]
And if we test it:
n = [4, 7, 1, 3, 2, 10]
doubled_odd_n = [2 * x for x in n if x % 2 != 0]
print doubled_odd_n
# Output: [14, 2, 6]
You can see how it removed all the even numbers and doubled the remaining odd numbers.
Example 4: Double odd numbers and half even numbers
For a bit more of a challenging example, let’s loop through all the numbers and double the odd numbers and half the even numbers. First thing to notice is that we aren’t filtering any numbers out so a conditional for the list comprehension is not necessary. Our processing will be handling the doubling and halving of values based on whether they are odd or even. To do this we can use an inline if statement. This means our processing part will look as follows:
x / 2 if x % 2 == 0 else 2 * x
This inline if statement will return the number halved if the number is even, otherwise it will return the double of the number.
This means our list comprehension will look as like:
manipulated_n = [x / 2 if x % 2 == 0 else 2 * x for x in n]
If we test out the code we will get the following results:
n = [1, 7, 3, 4, 10, 9]
manipulated_n = [x / 2 if x % 2 == 0 else 2 * x for x in n]
print manipulated_n
# Output: [2, 14, 6, 2, 5, 18]
As you can see our comprehensions able to double the odd numbers and half the even ones successfully.
Dictionary Comprehensions
A dictionary comprehension is similar to a list comprehension except it returns a dictionary of keys and values instead of a plain list.
Syntax of a Dictionary Comprehension
{key: value for iterate_list_or_dict if conditional}
As you can see the syntax for a Dictionary Comprehension is very similar to that of a List Comprehension. However, a Dictionary Comprehension is surrounded by {}
(curly braces). Python sees the curly braces and the syntax inside and is able to determine that this is a Dictionary Comprehension.
The first part is where we define the key and value combination to return to the new dictionary for the current item being processed. We always place our key first, then a :
and then the value.
We then iterate in the second part. We can iterate through the items in an array, or we can iterate through the keys and values of another dictionary.
Lastly we have our conditional statement again which we can use to filter out any data items from our final dictionary based on an item’s key or value.
Dictionary Comprehension Examples
Example 1: Create a dictionary of numbers and their squared values
For our first example, let’s create a dictionary of numbers and their corresponding squared values. In this case our numbers will be the key and the squared values will be the value. We will loop through a sequence from 1 to 10 to create this dictionary.
This will be our dictionary comprehension:
numbers_with_squares = {x: x*x for x in range(1, 11)}
If we test our code we will get the following:
numbers_with_squares = {x: x*x for x in range(1, 11)}
print numbers_with_squares
# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}
As you can see we can now access the square of each number by using the number as the key.
Example 2: Trim white-space from a dictionary with string values
In this example, we will be given a dictionary containing string details about a person. To make sure our data is neat, we want to go through each item in the dictionary and delete any leading or trailing white-space from each value. To loop through the dictionary we will use the dictionary’s iteritems()
method which lets us loop through both the keys and values. We will also use Python’s string’s strip()
method to eliminate any leading or trailing white-space.
Our dictionary comprehension should look something like this:
details_stripped = {key: value.strip() for key, value in details.iteritems()}
If we test our code we will get the following:
details = {
"name": "Ivan ",
"surname": " Kahl",
"email": " [email protected] "
}
details_stripped = {key: value.strip() for key, value in details.iteritems()}
print details_stripped
# Output: {'surname': 'Kahl', 'name': 'Ivan', 'email': '[email protected]'}
As you can see, we were able to trim all the white-space around the data successfully.
Example 3: Remove any items from a dictionary where the string value is empty
In this last example, we will iterate through a dictionary using a dictionary comprehension and remove any items in an existing dictionary that are empty/blank. To do this, we need to have a conditional expression that will return True if the value is not empty.
Our dictionary comprehension would then look like this:
nonempty_data = {key: value for key, value in data.iteritems() if value != ""}
This is what will happen when we test our code:
data = {
"song_name": "Hey There Delilah",
"artist": "Plain White T's",
"key": "D",
"strumming_pattern": "",
"timing": ""
}
nonempty_data = {key: value for key, value in data.iteritems() if value != ""}
print nonempty_data
# Output: {'song_name': 'Hey There Delilah', 'key': 'D', 'artist': "Plain White T's"}
As you can see our comprehension successfully returned only the items that had a non-empty value.
Conclusion
As you can see, Python provides some neat tools that let you create elegant solutions. These tools are incredibly powerful once you understand how to use them and often have many performance benefits. These comprehensions are just one of the powerful tools that Python provides. I encourage you to learn more Pythonic techniques that you can utilise in your coding.
I hope this post helped you and if you have any comments, questions or suggestions, please leave them in the comments below and I will get back to you.