~5 min read|
Python has a very concise syntax for creating new lists called List Comprehension.
List comprehension is a way to define a new list based on an old one.
In this post I’ll:
The syntax for a list defined with list comprehension has four pieces (some of which are optional):
for el in old_list
if el != None
This looks like:
new_list = [el for el in old_list if el != None ]
NB: The expression must reference the variable used to to find elements in the old list. So while
new_list = [el for el in old_list] is valid,
new_list = [number for el in old_list] will throw an error. The same is true for the filter.
First up, creating a list of odd numbers between 1 and 10 in Python.
We begin by constructing our base list:
>>> numbers =  >>> for number in range(1,11): ... numbers.append(number) ... >>> numbers [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Now we want to filter out odd numbers, we could use the same for loop strategy:
>>> odd_numbers =  >>> for number in numbers: ... if number % 2 != 0: ... odd_numbers.append(number) ... >>> odd_numbers [1, 3, 5, 7, 9]
But list comprehension allows a more concise syntax:
>>> odd_numbers = [number for number in numbers if number % 2 != 0] >>> odd_numbers [1, 3, 5, 7, 9]
But what if we didn’t want to filter. Instead we wanted to transform - doubling each number in the list for example:
>>> doubles = [number * 2 for number in numbers] >>> doubles [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
And now putting that together - filtering out the evens, and then tripling the remaining values:
>>> triple_odds = [number * 3 for number in numbers if number % 2 != 0] >>> triple_odds [3, 9, 15, 21, 27]
Now that we understand list comprehension, we can see that we could have created our first list more concisely too:
>>> numbers = [number for number in range(1,11)] >>> numbers [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Before moving on, let’s look at those side-by-side to see how list comprehension mirrors the syntax of the for-loop / if-statement:
>>> numbers = [number for number in range(1,11)] >>> numbers [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> triple_odd = [number * 3 for number in numbers if number % 2 != 0] >>> triple_odd [3, 9, 15, 21, 27] >>> triple_odd =  # reset the variable >>> for number in numbers: ... if number % 2 != 0: ... triple_odd.append(number * 3) ... >>> triple_odd [3, 9, 15, 21, 27]
The expressions are almost identical, though the list comprehension is in one line:
number * 3is the expression in the list comprehension in the first position. It is the last thing to occur in our for/if statement.
if number % 2 != 0is the filter in the list comprehension (last position), and the middle place in the for/if statement.
for number in numbersis the loop over the old list and is in the second position of our list comprehension and kicks off the for/if statement.
One of the interesting things about learning a new language is to see how it compares to others.
We get a hint for how to approach this from the documentation on array comprehensions:
Since array comprehension was about combining maps and filters, we’ll likely be able to achieve the same results by combining those.
Let’s take a look at the same example above of creating a numbers array, then finding an odd numbers and a triple odd numbers list.
First, let’s be fancy and use
Array.from() and it’s second argument, which is a map to generate our range of numbers 1-10.1
let numbers = Array.from(new Array(10), (_, i) => i + 1) console.log(numbers) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Now, we can create a filter to get our odd numbers:
let oddNumbers = numbers.filter((num) => num % 2 !== 0) console.log(oddNumbers) // [1, 3, 5, 7, 9]
And for our triple odd numbers:
let tripleOddNumbers = numbers .filter((num) => num % 2 !== 0) .map((odd) => odd * 3) console.log(tripleOddNumbers) // [3, 9, 15, 21, 27]
In our case, the order actually does not matter, however filtering before mapping is slightly more efficient as we reduce the number of elements we’ll need to map over:
let tripleOddNumbers = numbers .map((number) => number * 3) .filter((number) => number % 2 !== 0) console.log(tripleOddNumbers) // [3, 9, 15, 21, 27]
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!