使用列表推导在Python中转置多维矩阵
我有一个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))]