Online Book Reader

Home Category

Learning Python - Mark Lutz [272]

By Root 1654 0
by rows, to collect the second column we can simply iterate across the rows and pull out the desired column, or iterate through positions in the rows and index as we go:

>>> [row[1] for row in M]

[2, 5, 8]

>>> [M[row][1] for row in (0, 1, 2)]

[2, 5, 8]

Given positions, we can also easily perform tasks such as pulling out a diagonal. The following expression uses range to generate the list of offsets and then indexes with the row and column the same, picking out M[0][0], then M[1][1], and so on (we assume the matrix has the same number of rows and columns):

>>> [M[i][i] for i in range(len(M))]

[1, 5, 9]

Finally, with a bit of creativity, we can also use list comprehensions to combine multiple matrixes. The following first builds a flat list that contains the result of multiplying the matrixes pairwise, and then builds a nested list structure having the same values by nesting list comprehensions:

>>> [M[row][col] * N[row][col] for row in range(3) for col in range(3)]

[2, 4, 6, 12, 15, 18, 28, 32, 36]

>>> [[M[row][col] * N[row][col] for col in range(3)] for row in range(3)]

[[2, 4, 6], [12, 15, 18], [28, 32, 36]]

This last expression works because the row iteration is an outer loop: for each row, it runs the nested column iteration to build up one row of the result matrix. It’s equivalent to this statement-based code:

>>> res = []

>>> for row in range(3):

... tmp = []

... for col in range(3):

... tmp.append(M[row][col] * N[row][col])

... res.append(tmp)

...

>>> res

[[2, 4, 6], [12, 15, 18], [28, 32, 36]]

Compared to these statements, the list comprehension version requires only one line of code, will probably run substantially faster for large matrixes, and just might make your head explode! Which brings us to the next section.

Comprehending List Comprehensions

With such generality, list comprehensions can quickly become, well, incomprehensible, especially when nested. Consequently, my advice is typically to use simple for loops when getting started with Python, and map or comprehensions in isolated cases where they are easy to apply. The “keep it simple” rule applies here, as always: code conciseness is a much less important goal than code readability.

However, in this case, there is currently a substantial performance advantage to the extra complexity: based on tests run under Python today, map calls are roughly twice as fast as equivalent for loops, and list comprehensions are usually slightly faster than map calls.[43] This speed difference is generally due to the fact that map and list comprehensions run at C language speed inside the interpreter, which is much faster than stepping through Python for loop code within the PVM.

Because for loops make logic more explicit, I recommend them in general on the grounds of simplicity. However, map and list comprehensions are worth knowing and using for simpler kinds of iterations, and if your application’s speed is an important consideration. In addition, because map and list comprehensions are both expressions, they can show up syntactically in places that for loop statements cannot, such as in the bodies of lambda functions, within list and dictionary literals, and more. Still, you should try to keep your map calls and list comprehensions simple; for more complex tasks, use full statements instead.

* * *

Why You Will Care: List Comprehensions and map


Here’s a more realistic example of list comprehensions and map in action (we solved this problem with list comprehensions in Chapter 14, but we’ll revive it here to add map-based alternatives). Recall that the file readlines method returns lines with \n end-of-line characters at the ends:

>>> open('myfile').readlines()

['aaa\n', 'bbb\n', 'ccc\n']

If you don’t want the end-of-line characters, you can slice them off all the lines in a single step with a list comprehension or a map call (map results are iterables in Python 3.0, so we must run them through list to see all their results at once):

>>> [line.rstrip() for line in open('myfile').readlines()]

['aaa', 'bbb', 'ccc']

Return Main Page Previous Page Next Page

®Online Book Reader