2009-12-11 48 views
2
* N名单

我想在Python中创建一个3维n ňñ列表,像这样:问题创造N * N在Python

n=3 
l = [[[0,]*n]*n]*n 

不幸的是,这似乎不正确“克隆”的名单,因为我认为它会:

>>> l 
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]] 
>>> l[0][0][0]=1 
>>> l 
[[[1, 0, 0], [1, 0, 0], [1, 0, 0]], [[1, 0, 0], [1, 0, 0], [1, 0, 0]], [[1, 0, 0], [1, 0, 0], [1, 0, 0]]] 

我在做什么错在这里?

+0

如果你期望做很多矩阵运算,你可以进入'numpy',但我喜欢使用由元组索引的字典作为多维数组:'from collections import defaultdict; d = defaultdict(int); d [0,0,0] = 1' - 它可能非常适合你的3D井字游戏。 – 2012-07-26 00:44:39

回答

5

问题是* n做了一个列表的浅表副本。解决方案是使用嵌套循环,或尝试numpy库。

2

这不是克隆列表。它一遍又一遍地插入对同一个列表的引用。尝试使用一组嵌套的for循环创建列表。

3

正如其他人所提到的,它正在建立第二层和第三层的引用,而不是克隆。尝试:

>>> n = 3 

>>> l = [[[0]*n for _ in xrange(n)] for _ in xrange(n)] 

>>> l[0][0][0] = 1 

>>> l 
[[[1, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]] 

或者,如果你想输入一个少一点:

>>> l = [[[0]*n for _ in '.'*n] for _ in '.'*n] 
4

如果你想要做的数值处理与3-d矩阵你是使用numpy的更好。这是很容易:

>>> import numpy 
>>> numpy.zeros((3,3,3), dtype=numpy.int) 
array([[[0, 0, 0], 
     [0, 0, 0], 
     [0, 0, 0]], 

     [[0, 0, 0], 
     [0, 0, 0], 
     [0, 0, 0]], 

     [[0, 0, 0], 
     [0, 0, 0], 
     [0, 0, 0]]]) 
>>> _[0,0,0] 
0 
2

我有什么第二莱昂纳多 - santagada建议,增加的是创建N个维数组/列表是非常unpythonic,你应该重新考虑你如何保持你的数据,如果看在类别或词典列表(或列表字典)中不属于更好的类别。

+0

谢谢你指出这一点。我需要这个为AI算法创建一个三维井字棋板。尽管numpy数组可能加快了某些操作,但我认为这对于这个小程序来说“足够好”。 – 2009-12-18 19:03:48