使用列表推导在Python中转置多维矩阵

1 投票
2 回答
2821 浏览
提问于 2025-04-17 13:39

我有一个Python作业,要求我在不使用任何for循环的情况下,转置一个多维矩阵(比如3x3、4x4、5x5等),只能用列表推导式。

举个例子,对于一个2x2的矩阵,我们有:

a2 = [[1, 2], [3, 4]]
n = len(a2)
print [[row[i] for row in a2] for i in range(n)]

但我不太确定我是否真的理解它是怎么工作的,或者如何把它改编成3x3、4x4、5x5这样的矩阵。

比如说,对于

a3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

我并不一定希望你给我答案(我还是想自己搞明白),但任何提示都会很有帮助!

提前谢谢你!

2 个回答

6

我想你在你的例子里已经有了这个...

a2 = [[1, 2], [3, 4]]  #2x2
n = len(a2)
print [[row[i] for row in a2] for i in range(n)]

a2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]  #3x3
n = len(a2)
print [[row[i] for row in a2] for i in range(n)]

这个对象:

a3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

并不是2x2、3x3或者4x4的,而是2x2x2的。你需要具体解释一下在这种数据结构中,transpose是什么意思。

顺便提一下,如果你不把列表推导作为限制的话,使用zip,正如Lattyware所提到的,才是你应该采用的方法——我只是想指出你的解决方案已经适用于NxN的情况。

5

这里有一个内置的功能 - 就是 zip() 函数

>>> list(zip(*[[1, 2], [3, 4]]))
[(1, 3), (2, 4)]

需要注意的是,调用 list() 是为了展示结果。在 Python 3.x 中,这个函数会返回一个可迭代的对象,而不是一个列表(这样做可以节省内存)。而在 2.x 版本中,它无论如何都会返回一个列表。

如果你想在有更多嵌套列表的例子中也转置内部的部分,那么使用列表推导式来对子列表运行 zip() 是相对简单的。

这里有一个 2.x 版本的例子,方便阅读:

>>> zip(*(zip(*part) for part in [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]))
[((1, 3), (5, 7)), ((2, 4), (6, 8))]

撰写回答