14

我只是想用 Python 创建一个空的 10*3*2 数组。

我首先想到了这些,但这不起作用:

parameters = [ [ [] * 2 ]*3 ] * 10

这给了我一个由十个向量组成的向量,其中包含三个 [] 元素:

[[[], [], []], [[], [], []], [[], [], []], [[], [], []], [[], [], []], 
[[], [], []], [[], [], []], [[], [], []], [[], [], []], [[], [], []]]

也就是说,如果我想访问 parameters[0][0][1] 我超出了界限,而我想要一个维度 2 用于沿第三维的最里面的向量。

然后我想到了这个

[ [ [[] * 2] ]*3 ] * 10

我在想[[] * 2]现在会给我带来我想要的东西,一个最里面的两个元素向量。我得到

[[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], 
[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], 
[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]]]

那么,该怎么做,或者如何逃避这个初始化呢?

Kd rgds。

4

6 回答 6

25

我建议你使用 Numpy 来处理这类事情。它使访问列或行变得更加容易。对于您的用例,您会这样做

import numpy as np

matrix = np.zeros((2,3,10))
second_col = matrix[:,1,:]

Numpy 还将更好地处理您的数据,并且它在 Fortran 或 C 中实现了许多矩阵代数,因此当您进行矩阵乘法等时,它在(可能的)未来会更快。

于 2012-11-12T16:35:33.190 回答
24

首先,你应该在最里面的列表中插入一些东西(比如无)。其次,当您在最外层列表中使用乘法时,它会复制对内部列表的引用,因此当您更改一个元素时,您也会在所有其他列表中更改此元素:

>> parameters = [ [ [None] * 2 ]*3 ] * 10
>> print parameters
[[[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]]]
>> parameters[0][0][1]=1
>> print parameters 
[[[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]]]

因此,您应该使用列表推导:

>> parameters=[[[None for i in range(2)] for j in range(3)] for k in range(10)]

但是,我建议numpy按照其他答案之一中的建议使用。

于 2012-11-12T16:41:17.410 回答
7

这是您正在做的事情的问题之一。

假设您正在创建一个数组,如下所示:

>>> l = [ [ [[] * 2] ]*3 ] * 10
>>> l
[[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]]]

到目前为止似乎还可以。让我们在数组中设置一些东西。

>>> l[0][0][0] = 2
>>> l
[[[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]]]

哇!我们在其中设置了 1 个项目,但它改变了一切!那是怎么发生的?

好吧,看来我们有 60 个列表对象。然而,我们实际上对一个列表对象有 60 次引用。换一个,全部换。

TL;DR:不要在列表列表中使用乘法运算符。

于 2012-11-12T16:45:32.550 回答
6

我会做这样的事情,使用这个创建的列表是不同的对象(即不同的id()):

In [96]: [ [ [ []*2] for _ in range(3)] for _ in range(10) ]
Out[96]: 
[[[[]], [[]], [[]]],
 [[[]], [[]], [[]]],
 [[[]], [[]], [[]]],
 [[[]], [[]], [[]]],
 [[[]], [[]], [[]]],
 [[[]], [[]], [[]]],
 [[[]], [[]], [[]]],
 [[[]], [[]], [[]]],
 [[[]], [[]], [[]]],
 [[[]], [[]], [[]]]]

In [98]: [id(x) for x in lis]   #all objects are unique
Out[98]: 
[151267948,
 151268076,
 151268492,
 151269164,
 151267276,
 151265356,
 151268140,
 151269036,
 151265644,
 151265964]


In [101]: lis1=[ [ [[] * 2] ]*3 ] * 10

In [102]: [id(x) for x in lis1]    # all objects are same, changing one will change 
                                   # others as well
Out[102]: 
[151278188,
 151278188,
 151278188,
 151278188,
 151278188,
 151278188,
 151278188,
 151278188,
 151278188,
 151278188]
于 2012-11-12T16:35:39.077 回答
2
# Creates an n x n matrix in p
n=int(input())
p=[[[] for x in range(1,10)]for x in range(1,10)]
print(p)
于 2018-05-17T07:35:29.010 回答
0

做你想做的事情的正确方法是:

parameters = [ [ [[]] * 2 ]*3 ] * 10
parameters_mat = eval(str(parameters))

或者,或者:

parameters = [ [ ['0'] * 2 ]*3 ] * 10
parameters_mat = eval(str(parameters))

这样,你也解决了@btel提出的问题

于 2021-07-29T14:32:18.740 回答