只是为了给您一些背景信息:
我必须将一些 MATLAB 代码转换为 Python 3 代码,但在这里我遇到了一个小问题。
Matlab:
for i in 1:num_nodes
for j in 1:num_nodes
K{i,j} = zeros(3,3);
我翻译成:
k_topology = [[]]
for i in range(x):
for i in range(x):
k_topology[[i][j]].extend(np.zeros(3,3))
此外,Matlab 代码中还有第三个循环:
for k in 1:3
K{i,j}(k,k) = -1
这也有点......让我心烦意乱?
事实是我真的不知道如何将这种变量翻译成Python。另外,我猜我的 Python 代码有点“损坏” - 并且我并不是真的要求你们任何人改进它 - 所以我只是问哪一个是最好的如何将Matlab的单元格翻译成Python?
<小时/>我终于找到了一些显然简单的东西来翻译这个,使用列表理解 - 根据kazemakase的答案。实际的 Python 代码现在如下所示:
k_topology = [[np.zeros((3,3)) for j in range(self.get_nb_nodes_from_network())]\
for i in range(self.get_nb_nodes_from_network())]
输出中看起来像这样:
[[array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]),
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]),
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])], ..., [array(...)]]
(确实有太多值无法粘贴到此处,但我想您已经明白了。)
最佳答案
您需要问的第一个问题是“什么是 Matlab 单元以及什么可能是合适的相应 Python 类型?”
如果我没记错的话,在我糟糕的过去的 Matlab 岁月里,单元格是一种容纳混合类型内容的容器。它类似于动态类型的数组或矩阵。它是多维索引的。
Python是动态类型的,所以任何Python容器基本上都可以实现这个功能。 Python 中的列表是有索引的,因此嵌套列表可以工作 - 但它们的设置和访问有点奇怪:
K = [[None] * num_nodes for _ in range(num_nodes)]
K[i][j] # need two indices to access elements of a nested list.
对于特定场景,字典可以更好地反射(reflect) Matlab 语法。虽然字典只需要一个索引,但我们可以利用这样一个事实:元组可以在没有括号的情况下声明,并且字典可以将元组作为索引:
K = {}
for i in range(num_nodes):
for j in range(num_nodes):
K[i, j] = np.zeros((3, 3))
for k in 1:3
K[i, j][k, k] = -1
虽然字典在语法上更简洁,但元素访问的性能可能不如嵌套列表。嵌套看起来与 Matlab 代码不同。选择取决于性能或与原始代码的相似性。但如果性能是一个问题,那么无论如何还有很多事情需要考虑。总之:没有一种最好的方法。
<小时/>由于OP明确要求不要改进代码,我明确要求他/她忽略这部分答案。
构建对角矩阵的更好方法是使用 np.ones
而不是循环对角元素。
K = {}
for i in range(num_nodes):
for j in range(num_nodes):
K[i, j] = -np.ones((3, 3))
此外,如果这是首选方法,则可以在没有(太多)事先初始化的情况下构造嵌套列表:
K = []
for i in range(num_nodes):
K.append([])
for j in range(num_nodes):
K[-1].append(-np.ones((3, 3)))
<小时/>
现在,为了我灵魂的平静,让我分解提供有关OP代码的反馈:
k_topology = [[]] for i in range(x): for i in range(x): k_topology[[i][j]].extend(np.zeros(3,3))
- 这与原始Matlab代码无关(变量名称不同)
- 两个循环都使用
i
。j
从未定义。 [[i][j]]
使用一个元素i
构建一个列表,并尝试获取第 j 个元素。如果j
不是 0,这将导致错误。list.extend
a 将参数的所有元素单独附加到列表中 - 在本例中为单独的行。list.append
使用起来是正确的,因为整个 3x3 矩阵应作为一个元素附加到 K 中。np.zeros(3, 3)
应为np.zeros((3, 3))
(假设np
是别名对于numpy
),因为该函数采用的形状是第一个参数,而不是多个参数。
关于python - 如何在 Python 3 中转换 MATLAB 单元格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42252785/