11 Examples to Master Python List Comprehensions | by Soner Yıldırım | Towards Data Science

List is a built-in data structure in Python and a collection of data points in square brackets. Lists can be used to store any data type or a mixture of different data types.
In this post, we will cover list comprehensions in python with 11 examples. I tried to order the examples according to their complexity levels (in my opinion).
List comprehension is basically creating lists based on existing iterables. It can also be described as representing for and if loops with a simpler and more appealing syntax. List comprehensions are relatively faster than for loops.
So we iterate over an iterable and do something (optional!) with the items and then put them in a list. In some cases, we just take the items that fit a specified condition.
Let’s start with the examples.
#example 1import numpy as npa = [4,6,7,3,2]b = [x for x in a if x > 5]b[6, 7]
We iterate over a list (iterable) and take the elements that are greater than 5 (condition).
The equivalent for loop is:
b = []for x in a:  if x > 5:    b.append(x)b[6, 7]
We can also do something with items before putting them in a new list:
#example 2import numpy as npa = [4,6,7,3,2]b = [x*2 for x in a if x > 5]b[12, 14]
We multiply the items that fit the condition by 2 and then put in a list.
The third example is a list of strings:
#example 3names = ['Ch','Dh','Eh','cb','Tb','Td']new_names = [name for name in names if name.lower().startswith('c')]new_names['Ch', 'cb']
The condition is that string starts with the letter “c”. Since we have both capital and lowercase letters, we convert all letters to lowercase first.
The iterable does not have to be a list. It can be any python iterable. For instance, we can iterate over a 2-dimensional NumPy array which is actually a matrix.
#example 4import numpy as npA = np.random.randint(10, size=(4,4))Aarray([[1, 7, 4, 4],               [5, 0, 0, 6],               [7, 5, 8, 4],               [1, 3, 2, 2]])max_element = [max(i) for i in A]max_element[7, 6, 8, 3]
We iterate over the rows in matrix A and take the maximum number.
Lists can store any data type. Let’s do an example with a list of lists.
#example 5vals = [[1,2,3],[4,5,2],[3,2,6]]vals_max = [max(x) for x in vals]vals_max[3, 5, 6]
We create a list of the maximum values in each list.
We can have multiple conditions in a list comprehension.
#example 6names = ['Ch','Dh','Eh','cb','Tb','Td','Chb','Tdb']new_names = [name for name in names if name.lower().endswith('b') and len(name) > 2]new_names['Chb', 'Tdb']
We get the strings that end with the letter “b” and have a length greater than 2.
We can combine multiple conditions with other logical operators:
#example 7names = ['chb', 'ydb', 'thd', 'hgh']new_names = [name for name in names if name.endswith('b') | name.startswith('c')]new_names['chb', 'ydb']
We can also have nested list comprehensions which are a little bit more complex. They represent nested for loops.
Consider the following list of lists:
vals = [[1,2,3],[4,5,2],[3,2,6]]
We want to take out each element from the nested lists so the desired output is:
vals = [1,2,3,4,5,2,3,2,6]
Here is the nested list comprehension that does this operation:
#example 8vals = [[1,2,3],[4,5,2],[3,2,6]]vals_exp = [y for x in vals for y in x]vals_exp[1, 2, 3, 4, 5, 2, 3, 2, 6]
The syntax may not seem very intuitive. It will be clear when compared with the equivalent for loop.
We put the blocks of a nested for loop into a list comprehension.
Note: There is a much easier way to do the operation in example 7 which is the explode function of pandas. I used list comprehension just to show the structure. It can be done with the explode function as follows:
pd.Series(vals).explode()
It returns a pandas series but you can easily convert it to a list.
We can also add conditions in nested list comprehensions. Consider the following list of lists with strings.
text = [['bar','foo','fooba'],['Rome','Madrid','Houston'], ['aa','bb','cc','dd']]
We only want the strings in nested lists whose length is greater than 3.
#example 9text_1 = [y for x in text if len(x)>3 for y in x]text_1['aa', 'bb', 'cc', 'dd']
We put the condition on the nested lists, not on individual elements. Thus, the equivalent nested for/if loop syntax is as follows.
We can also put a condition on individual elements.
#example 10text_2 = [y for x in text for y in x if len(y)>4]text_2['fooba', 'Madrid', 'Houston']
We now have strings that are longer than 4 characters. Since the condition is on individual elements, the equivalent nested for/if loops:
We may also need to put conditions on both nested lists and individual items.
#example 11text_3 = [y.upper() for x in text if len(x) == 3 for y in x if y.startswith('f')]text_3['FOO', 'FOOBA']
We get the items that start with the letter “f” in nested lists with a length of 3 and then convert all the letters of selected items to uppercase.
The equivalent for/if loops:
Tip: When you are not sure and cannot find out the syntax for list comprehension, try to build it with for/if loops. Then you can convert it to a list comprehension by adding individual blocks of loops into the list comprehension.
List comprehension loads the entire output list into memory. This is acceptable or even desirable for small or medium-sized lists because it makes the operation faster. However, when we are working with large lists (e.g. 1 billion elements), list comprehension should be avoided. It may cause your computer to crash due to the extreme amount of memory requirement.
A better alternative for such large lists is using a generator that does not actually create a large data structure in memory. A generator creates items when they are used. After the items are used, the generator throws them away. Using a generator, we can ask for the next item in an iterable until we reach the end and store a single value at a time.
Thank you for reading. Please let me know if you have any feedback.