Categories
Programming

An Ode to Python List Comprehensions

Natural Language is a great way to program computers. Who could have thought of that?

Whatever your opinion of Python may be, List Comprehensions are the most elegant way to operate on Lists/Arrays in any mainstream programming language. It also provides the clarity needed to work that is missing from other popular languages.

Lists and how it’s done.

An Array in most high-level languages, is an unordered list of data. It is usually denoted by [] . It is the same for other popular languages like Javascript and PHP. But they are called Lists in Python. The reason for this anomaly are beyond the scope right now.

An Array/List of numbers and characters would be:

[1,2,3,"a","b",45.5]

Now imagine you just want the characters from this Array.

How it’s done otherwise

Pre-2015 achieving this in Javascript was a hassle.

var array = [1,2,3,"a","b",45.5];
var length = array.length;
var characters = [];

for ( var i = 0; i < length; i++){
	if ( typeof array[i] == 'string' ) characters.push(array[i]);
}

console.log(characters);
//>> ['a','b']

Fortunately, this was resolved by the Elders of JS* in 2015.

console.log(array.filter(element => typeof element == 'string'))
//>> ['a','b']

There is just one problem; this is computationally more costly. It takes more resources to perform when compared to the previous method. Why? No one knows. This is never issue when you have tiny Array like this, but with real life data, it can slow everything down.

List Comprehensions

Python has it’s own single line solution for filtering Lists:

my_list = [1,2,3,"a","b",45.5]
print([element for element in my_list if type(element) == str])
#>> ['a','b']

Why is this beautiful?

Besides being as fast as a for loop, this statement summarizes python’s original philosophy of code-readability in a perfect manner. You can guess what’s going to happen just by reading the code. There are no ugly higher-order functions, no weird foreach loop. It is clear, concise and human.

Other Operations

Filter is not the only operation. Maybe you have a list of numbers that you want to square.

my_list = list(range(1,11)) # Generate a List of integers form 1 to 10
print([i**2 for i in my_list])
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
myArray = [1,2,3,4,5,6,7,8,9,10]
console.log(myArray.map(i => i**2))
//>> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

This type of operation is usually referred to as a Map. In JS, you achieve this by yet another Array object method and higher-order functions. The trouble happens when you want to apply multiple operations. Lets square all the odd numbers.

[i**2 for i in my_list if i % 2 == 1]
#[1, 9, 25, 49, 81]
myArray.
	filter(i => i % 2 == 1).
	map(i => i**2)
//[1, 9, 25, 49, 81]

This is the problem with most non-Python languages. The list comprehension, besides being beautiful is also very practical. List comprehension also aren’t just applied on lists. You can apply it to any iterator type object, like ranges, sets, etc. You also don’t have to generate lists. If you apply () instead of [] , you get an in-line Generator.

If you are a programmer, this is straight up magic. The ability to an otherwise complex task in such a simple way brings a clarity that is unexplainable. Programming is about solutions to problems. Many CS books and courses will tell you about best practices, and the ‘right way to do things’. In practice, you use the tools you have, and having something so simple yet powerful can give you the mental space to utilize those tools to their extent.


*Otherwise known as ECMA.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.