This article will explain what is list comprehension in python, how to use it along with applying conditions in it with sufficient examples.

List Comprehension
Suppose there is a list of numbers and you want a new list with the square of these numbers. Typically, you would write below code

numbers = [1,2,3,4,5]
# create an empty list
square = []
for num in numbers:
    square.append(num * num)

This method iterates over the list using a for loop and adds the square of list element to the new list using its append() method.

With List comprehension, same program can be written as

numbers = [1,2,3,4,5]
square = [num * num for num in numbers]

This will print

[1, 4, 9, 16, 25]

Thus, List comprehension is a concise and clean way of creating a list from an existing list or sequence.
List comprehension is written using the below syntax.

new_list = [ expression for item in existing_list ]

expression evaluates to a value and this value is assigned as an element to the new list.
expression is evaluated equal number of times as the for loop is executed.
expression has access to the variable defined in for loop.
existing_list may be a list, string or range() function.
Following are a few examples to clarify the working of list comprehension.
1. Creating a list from loop
Below code example iterates over a loop and creates a list out of it.

numbers = [num for num in range(10)]

2. Getting characters from a string
List comprehension can be used to create a list of characters in a string as shown below.

characters = [char for char in 'codippa']

which prints

[‘c’, ‘o’, ‘d’, ‘i’, ‘p’, ‘p’, ‘a’]

3. Creating a list from an existing list
This, we already saw in the previous section.

Cloning a list
List comprehension can also be used to create a copy of a list. List created with comprehension and the original list are different from each other.
Look at below example program

numbers = [1,2,3,4,5]
print('Original list: ', numbers)
square = [num * num for num in numbers]
print('Are Lists equal?', square == numbers)
numbers[0] = 5
print('Original list after change:', numbers)
print('Comprehended list:', square)

This example creates a list of squares with comprehension syntax, compares both the lists with == operator. Then it changes the first element of the original list and prints both the lists.

Original list: [1, 2, 3, 4, 5]

Are Lists equal? False

Original list after change: [5, 2, 3, 4, 5]
Comprehended list: [1, 4, 9, 16, 25]

Look, both the lists are different and changing the first element of the source list does not change the list created with comprehension.
Conditionals in comprehension
It might happen that we want only selective elements from the original sequence to be added to the new list. That is, we want to add elements only when they meet some condition.
We can do that using an if condition in List comprehension. Syntax is

new_list = [ expression for item in existing_list if condition]

Value returned from the expression will only be added to the list when the condition is satisfied or the condition is True.

Example, suppose we want to create a list of even numbers till 50. With list comprehension and if condition, we can do that as below

even_numbers = [ num for num in range(31) if num % 2 == 0 ]
print('List of even numbers till 30:')

This example iterates a loop from 0 till 30 and checks whether loop item is divisible by 2 using modulus operator(%).
If the condition num % 2 == 0 is True, the item will be added to the list.
Output of this program is

List of even numbers till 30:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]

which shows that the if condition works fine with list comprehension.
This is also called filtering since the elements are being filtered out.

Suppose we are filtering a list with an if condition as shown above. We may want to take some action in case the if condition evaluates to False.

Python list comprehension also allows to write an ifelse condition. This means that when if condition evaluates to False, else condition is executed.
Syntax is

new_list = [ expression if condition1 else condition2 for item in existing_list ]

Example, for every odd number till 20, below program writes -1 to the resultant list using an ifelse construct.

numbers = [ num if num % 2 == 0 else -1 for num in range(21)]
print('List of numbers till 20:')

This prints

List of numbers till 20:
[0, -1, 2, -1, 4, -1, 6, -1, 8, -1, 10, -1, 12, -1, 14, -1, 16, -1, 18, -1, 20]

where all odd numbers are replaced with -1.
Note that when ifelse is used, you need to place it before the loop.
Nested List comprehension
Till now, we saw how to create a list from another list by accessing its elements. But what if each element of the list is another list or for string values, if each of the element is another string.
In such case, comprehension is used twice which is also called Nested Comprehension just like we have nested loops.

Basically, where two levels of iteration is required, you can use Nested Comprehension. Also, remember that nested comprehension creates a list of list.

Syntax of nested list comprehension is

result_list = [[ expression for item_inner in inner_list ] for inner_list in outer_list]

Each element of outer_list is a list. This list is supplied to the inner loop which iterates over each of its element.
is the final element which is added or appended to the result list.
Suppose we have a list of list of numbers and we want a new list whose each element is a square of the original list. Without list comprehension, the program will be

list_of_list = [[1,2],[3,4]]
# list to hold list of squares
squares = []
# iterate over list of list
for inner_list in list_of_list:
    # list to hold square of elements
    inner_squares = []
    # iterate over inner list
    for num in inner_list:
        # square each element and add it to list
        inner_squares.append(num * num)
    # append list to squares list
print('Original List:', list_of_list)
print('List of squares:', squares)

which prints

Original List: [[1,2], [3,4]]

List of squares: [[1, 4], [9, 16]]

Same can be achieved with nested list comprehension with below code

squares = [[ num * num for num in inner_list ] for inner_list in list_of_list ]

Conditions in nested comprehension
ifelse conditions can be applied to nested comprehension in the same manner as to single comprehension.
When the condition is applied to the outer comprehension and it is False, inner comprehension will not receive the list that it should iterate on.

When the condition is applied to the inner comprehension and it is False, then the element will not be added to the resultant list.

Example, suppose we need to remove all vowels from a list of words and create a new list with those words. This involves two levels of iteration and so, nested comprehension can be applied.

words = ['python', 'programming', 'is', 'fun']
# list of vowels
vowels = ['a', 'e', 'i', 'o', 'u' ]
# add only those letters which are not vowels
without_vowels = [ [letter for letter in word if letter not in vowels] for word in words]

Notice the if condition in the inner comprehension which checks if each letter is not present in list of vowels.

This prints

[[‘p’, ‘y’, ‘t’, ‘h’, ‘n’], [‘p’, ‘r’, ‘g’, ‘r’, ‘m’, ‘m’, ‘n’, ‘g’], [‘s’], [‘f’, ‘n’]]

Every element in the outer list is another list with vowels removed from its elements. Remember Nested comprehension creates a list of list.
But this is not what we wanted. We would get the desired result if we combine the elements of inner list using join() function as shown below.

without_vowels = [ ''.join([letter for letter in word if letter not in vowels]) for word in words]

This will print

[‘pythn’, ‘prgrmmng’, ‘s’, ‘fn’]

which was the desired result.
Functions in Comprehension
A python function can be used in place of an expression in comprehension syntax. Only condition is that it should return a value that shall be added to the result list.

Thus, earlier example which created a list of squares can be modified as

# function to return the square of its argument
def get_squares(num):
    return num * num

# create a list
numbers =[1,2,3,4,5]
# create square list
squares = [get_squares(num) for num in numbers]

Notice how in place of expression, we are invoking a function that returns the square of list element.

Functions can also be used in if condition that is used to filter elements in comprehension. This function should return True or False.
If it returns True, the element will be added to the list else not.

Thus, the example to filter out non-vowel letters in the previous section can be modified to use a function in the if condition as below

vowels = ['a', 'e', 'i', 'o', 'u' ]

# check if the letter is a vowel or not
def is_vowel(letter):
    return letter not in vowels

words = ['python', 'programming', 'is', 'fun']
without_vowels = [ ''.join([letter for letter in word if is_vowel(letter)]) for word in words]

Look how it uses a function in the if condition which checks whether the letter is a vowel.

Hope the article was helpful in explaining the concept of list comprehension in python. Hit the clap to appreciate.

Liked the article ? Spread the word...

Leave a Reply