Python Comprehension List with Examples
Python Comprehension List with Examples

Introduction

List comprehension is mighty and must know idea in Python. Yet, this remains one of the most claim topics for beginners. With this post, I resolve to help each one of you who is facing this anxiety in python. Mastering this concept would help you in two ways:

  1. You would start writing shorter and effective codes
  2. Hence, your code will execute faster

Do you know List Comprehensions are 35% brisk than FOR loop and 45% faster than map function? I detected these and many other interesting facts in this post.

If you are reading this, I’m sure either you want to learn it from a scrape or become better at this concept. Both ways, this post will help you.

What is List Comprehension (LC)?

When I first used LC, it took me down the memory lane and warned me of the set-builder form. Yes, you got me right. Set maker is a concept mostly taught in Class XI in India. (check this). I’ve perfect some of the easy examples from this textbook to clarify this concept.

Let us look at some of the basic examples with analogous Python codes implementing LC:

{ x^2: x is a natural number less than 10 }

 

{ x: x is a whole number less than 20, x is even }

 

{ x: x is an alphabet in word ‘MATHEMATICS’, x is a vowel }

 

Don’t worry even if it feels a bit foggy. Just hang on with me, things will develop into more clear as we proceed. Let’s take a step back and see what’s happening here. Each of the above examples involves 3 things – iteration, conditional filtering and processing. Hence, you might say it’s just another representation of FOR loop.

How ‘For’ loop works?

 

With LC

 

Consider another example: { x: x is a natural number less than or equal to 100, x is a perfect square }
This can be solved using a for-loop as:

Now, to create the LC code, we need to just plug in the different parts:

I hope it is making more sense now. Once you get a hang of it, LC is a simple but powerful correspond and can help you manage a variety of tasks with ease. Things to preserve in mind:

1. LC will always entry a result, whether you use the reaction or nor.

2. The iteration and conditional expressions can be nested with multiple details.

3. Even the overall LC can be nested inside another LC.

4. Multiple variables can be iterated and manipulated at a same time.

Predefined functions might exist forgive out the tasks explained below, but these are best examples to get a grasp of LC.

Flatten a Matrix example

Aim: Take a matrix as input and arrival a list with each row fixed on after the other.

Python codes with FOR-loop and LC implementations:

Let’s define a form and test the results:

Output:

The Time advantage

In this branch, we will find out the time taken by LC in ratio to similar techniques. We will also try to unravel the situations in which LC works better and where it should be avoided. Along with runtime, we will compare the readability of the various approaches.

Before jumping into comparing the time taken by different techniques, let’s take a cordial on the Python map function.

map function

It is used to apply an affair to each item of a list or any other iterable.
Syntax: map(function, Python iterable)

For example, we can multiply each element of a list of integers with the next total using the following code:

Comparing Runtime

An important part of this task is the capability to compare the running time of a code fragment. We will be using %timeit, an inbuilt magic function of iPython notebook environment. sooner, you can use the time or time modules.

We will be comparing the runtimes of implementation of the same result using LC, FOR-loop and map function. Also, we shall focus on the analogous run times and not the absolute values because it is subject to the machine specs. FYI, I am using a Dell XPS 14Z system with following specs:
2nd Gen i5 (2.5GHz) | 4GB RAM | 64-bit OS | Windows 7 Home Premium

A Simple Example

Let’s start with a simple example – squaring each element of a list. The Python codes and runtimes for each of the 3 implementations are:

Output: 100000 loops, best of 3: 2.69 µs per loop

Output: 100000 loops, best of 3: 3.16 µs per loop

Output: 100000 loops, best of 3: 1.67 µs per loop

RunTime: We can clearly see that in this case LC is ~35% faster than for-loop and ~45% faster than map function.
Readability: Both LC and map functions are fairly simple and readable, but for-loop is a bit bulky but not much.
So can we say LC is the fastest method? Not necessary! We can’t generalize our conclusions at this stage as it might be specific to the problem at hand. Let’s consider a slightly tricky example.

Taking a step forward

Let’s include a catch in above problem. What if we wish the square of only even numbers in the list? Now, the three functions would look like:

Output: 100000 loops, best of 3: 2.31 µs per loop

Output: 100000 loops, best of 3: 5.25 µs per loop

Output: 100000 loops, best of 3: 1.74 µs per loop

RunTime: LC is ~25% faster than for-loop and ~65% faster than map function.
Readability: LC is most concise and elegant. Map task became cumbersome with additional lambda function and for-loop is no better.

Getting into crux of the matter

Let’s compare each conclusion on 3 fronts:
1. Iterating over the list
2. Modifying each element
3. Storing the result

lets call a simple function that has no agreement with doing anything and primary role is an emphasis.

The codes and runtime of each technique are:

Output: 1000000 loops, best of 3: 714 ns per loop

Output: 1000000 loops, best of 3: 2.29 µs per loop

Output: 1000000 loops, best of 3: 1.18 µs per loop

RunTime: FOR-loop is fastest. This is through in a for-loop, we need not return an element and just move onto next iteration using “pass”. In both LC and map, returning an element is necessary. The codes here return None. But still map takes more than twice the time. Intuitively, we can think that map involves a definite function call at each iteration which can be the logic behind the extra time. Let’s explore this at a later stage.

Generator Expressions (GE)

You must be wondering why should one use a generator! It works one-by-one, has some inherent equality to be kept in mind and it is not compatible with many functions and even additional libraries.

The biggest advantage is that generators have very low mind requirements as they return numbers on the fly. On the other hand, using simple LC will first create a list in memory and then sum it. However, generators might not perform well on small problems because they make many function calls making it heavy. It should be used for solving calculation which is too heavy on memory

Consider following functions:

I ran these functions for 3 different values of N and the runtimes are illustrated below:

Conclusions:

For small N, GE is relatively slower than LC. This is because of high different calls are required in GE but LC doesn’t require much space in memory.

For moderate N, GE performs almost the same as LC. GE requires a high number of calls and LC needs large memory block.

For very high N, generators are drastically powerful as LC takes ~70 times of the time taken by GE. This is because LC uses up a very large portion of RAM and processing becomes very slow.

See more:

how to write python script on ubuntu

Best Programming Resources to Learn Python