In the post Using lists with Python 3 I explained something about lists in Python, however, since Python is very slow in FOR-LOOPS, to generate lists Python supports a concept named “list comprehensions“. “list comprehensions” can be used to construct lists in a very natural and easy way, like a mathematician is used to do.

For example:

NEWLIST_LOOP = []
for counter in range(10):
    NEWLIST_LOOP.append(counter)

The above piece of code generates this list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], using list comprehensions the same list can be generated with the following line of code:

NEWLIST_COMP = [x for x in range(10)]

one line of code versus 3 lines of code….

List comprehensions advantages:

  • Compact notation:
    From the example above we have already seen the first advantage, we could write less code. And, as any SW developer knows “less code means less bugs”
  • Speed:
    Another effect on using LC is to have better performances, for example imagine you have a square matrix (10000×10000) and you want to flatten this matrix. Using for-loop
@time_fun
def flatten_for(matrix):
    flat = []
    for row in matrix:
        for x in row:
            flat.append(x)
    return flat

    and using LC

@time_fun
def flatten_lc(matrix):
    return [x for row in matrix for x in row]

to get the time spent I use the time_fun decorator explained at ()

if __name__ == '__main__':
    matr = generate_mat(10000)
    bbb = flatten_for(matr)
    ccc = flatten_lc(matr)
    if bbb == ccc:
        print("Q")

And the results will be:

flatten_for 8024.824380874634
flatten_lc 4652.031660079956

You can find the full source code for this example at ()

Let’s go ahead with other examples:

LIST_COMP_2 = [x**2 for x in range(10)]
print(LIST_COMP_2)

will generate a list containing the squares of the first 10 integers

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Imagine you want to create a new list containing all elements of list_comp_2 that are even, with for-loop code:

LIST_COMP_3 = []
for elem in LIST_COMP_2:
    if elem % 2 == 0:
        LIST_COMP_3.append(elem)
print(LIST_COMP_3)

And the results will be:

[0, 4, 16, 36, 64]

the same list using list comprehensions

LIST_COMP_4 = [x for x in LIST_COMP_2 if x%2 == 0]
print(LIST_COMP_4)

And the results will be:

[0, 4, 16, 36, 64]

all elements contained in both LIST_COMP_2 and NEWLIST_COMP that are even:

LIST_COMP_5 = [x for x in LIST_COMP_2 if x in NEWLIST_COMP and x%2 == 0]

And the results will be:

[0, 4]

the same list using for-loop

LIST_6 = []
for elem in LIST_COMP_2:
    if elem in NEWLIST_COMP:
        if elem%2 == 0:
            LIST_6.append(elem)

And the results will be:

[0, 4]

Really great concept.

You can find full source code for this blog post at my github at lists_and_comprehension.py