Expert Python Programming(Third Edition)
上QQ阅读APP看书,第一时间看更新

List comprehensions

As you probably know, writing a piece of code such as this can be tedious:

>>> evens = []
>>> for i in range(10):
...     if i % 2 == 0:
...         evens.append(i)
...   
>>> evens
[0, 2, 4, 6, 8] 

This may work for C, but it actually makes things slower for Python for the following reasons:

  • It makes the interpreter work on each loop to determine what part of the sequence has to be changed
  • It makes you keep a counter to track what element has to be processed
  • It requires additional function lookups to be performed at every iteration because append() is a list's method

A list comprehension is a better pattern for these kind of situations. It allows us to define a list by using a single line of code:

>>> [i for i in range(10) if i % 2 == 0]
[0, 2, 4, 6, 8]

This form of writing is much shorter and involves fewer elements. In a bigger program, this means less bugs and code that is easier to understand. This is the reason why many experienced Python programmers will consider such forms as being more readable.

List comprehensions and internal array resize
There is a myth among some Python programmers that list comprehensions can be a workaround for the fact that the internal array representing the list object must be resized with every few additions. Some say that the array will be allocated once in just the right size. Unfortunately, this isn't true.
The interpreter, during evaluation of the comprehension, can't know how big the resulting container will be, and it can't preallocate the final size of the array for it. Due to this, the internal array is reallocated in the same pattern as it would be in the   for  loop. Still, in many cases, list creation using comprehensions is both cleaner and faster than using ordinary loops.