5.1.4. 嵌套的列表推导式

列表推导式中的初始表达式可以是任何表达式,包括另一个列表推导式。

考虑下面这个 3x4的矩阵,它由3个长度为4的列表组成

  1. >>> matrix = [
  2. ... [1, 2, 3, 4],
  3. ... [5, 6, 7, 8],
  4. ... [9, 10, 11, 12],
  5. ... ]

下面的列表推导式将交换其行和列

  1. >>> [[row[i] for row in matrix] for i in range(4)]
  2. [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

如上节所示,嵌套的列表推导式是基于跟随其后的 for 进行求值的,所以这个例子等价于:

  1. >>> transposed = []
  2. >>> for i in range(4):
  3. ... transposed.append([row[i] for row in matrix])
  4. ...
  5. >>> transposed
  6. [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

反过来说,也等价于

  1. >>> transposed = []
  2. >>> for i in range(4):
  3. ... # the following 3 lines implement the nested listcomp
  4. ... transposed_row = []
  5. ... for row in matrix:
  6. ... transposed_row.append(row[i])
  7. ... transposed.append(transposed_row)
  8. ...
  9. >>> transposed
  10. [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

实际应用中,你应该会更喜欢使用内置函数去组成复杂的流程语句。 zip() 函数将会很好地处理这种情况

  1. >>> list(zip(*matrix))
  2. [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]

关于本行中星号的详细说明,参见 解包参数列表