50

我想在 Python (2.7) 中创建一个 3D 数组,以便像这样使用:

distance[i][j][k]

数组的大小应该是我拥有的变量的大小。(n n n)

我尝试使用:

distance = [[[]*n]*n]

但这似乎不起作用。

我只能使用默认库,并且乘法(即[[0]*n]*n)不起作用,因为它们链接到同一个指针,我需要所有值都是单独的

4

10 回答 10

77

您应该使用列表理解

>>> import pprint
>>> n = 3
>>> distance = [[[0 for k in xrange(n)] for j in xrange(n)] for i in xrange(n)]
>>> pprint.pprint(distance)
[[[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]]]
>>> distance[0][1]
[0, 0, 0]
>>> distance[0][1][2]
0

您可以使用看起来像您尝试过的语句生成一个数据结构,但是由于内部列表是按引用复制的,因此它会产生副作用:

>>> distance=[[[0]*n]*n]*n
>>> pprint.pprint(distance)
[[[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]]]
>>> distance[0][0][0] = 1
>>> pprint.pprint(distance)
[[[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]]]
于 2012-05-19T19:57:10.393 回答
42

numpy.arrays 专为这种情况而设计:

 numpy.zeros((i,j,k))

会给你一个维度 i j k 的数组,用零填充。

根据您的需要,numpy可能是满足您需求的正确库。

于 2012-05-19T19:47:03.867 回答
8

正确的方法是

[[[0 for _ in range(n)] for _ in range(n)] for _ in range(n)]

(你想要做的应该写成(对于NxNxN)

[[[0]*n]*n]*n

但这不正确,请参阅@Adaman 评论原因)。

于 2012-05-19T19:46:05.913 回答
5
d3 = [[[0 for col in range(4)]for row in range(4)] for x in range(6)]

d3[1][2][1]  = 144

d3[4][3][0]  = 3.12

for x in range(len(d3)):
    print d3[x]



[[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, 144, 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, 0, 0, 0], [0, 0, 0, 0]]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [3.12, 0, 0, 0]]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
于 2013-03-09T13:23:04.257 回答
4
"""
Create 3D array for given dimensions - (x, y, z)

@author: Naimish Agarwal
"""


def three_d_array(value, *dim):
    """
    Create 3D-array
    :param dim: a tuple of dimensions - (x, y, z)
    :param value: value with which 3D-array is to be filled
    :return: 3D-array
    """

    return [[[value for _ in xrange(dim[2])] for _ in xrange(dim[1])] for _ in xrange(dim[0])]

if __name__ == "__main__":
    array = three_d_array(False, *(2, 3, 1))
    x = len(array)
    y = len(array[0])
    z = len(array[0][0])
    print x, y, z

    array[0][0][0] = True
    array[1][1][0] = True

    print array

更喜欢numpy.ndarray用于多维数组。

于 2016-03-01T11:26:26.720 回答
3

您还可以使用for如下所示的嵌套循环

n = 3
arr = []
for x in range(n):
    arr.append([])
    for y in range(n):
        arr[x].append([])
        for z in range(n):
            arr[x][y].append(0)
print(arr)
于 2019-12-13T05:46:57.403 回答
1

有很多方法可以解决您的问题。

  1. 第一个是@robert 接受的答案。这是它的通用解决方案:
def multi_dimensional_list(value, *args):
  #args dimensions as many you like. EG: [*args = 4,3,2 => x=4, y=3, z=2]
  #value can only be of immutable type. So, don't pass a list here. Acceptable value = 0, -1, 'X', etc.
  if len(args) > 1:
    return [ multi_dimensional_list(value, *args[1:]) for col in range(args[0])]
  elif len(args) == 1: #base case of recursion
    return [ value for col in range(args[0])]
  else: #edge case when no values of dimensions is specified.
    return None

例如:

>>> multi_dimensional_list(-1, 3, 4)  #2D list
[[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]]
>>> multi_dimensional_list(-1, 4, 3, 2)  #3D list
[[[-1, -1], [-1, -1], [-1, -1]], [[-1, -1], [-1, -1], [-1, -1]], [[-1, -1], [-1, -1], [-1, -1]], [[-1, -1], [-1, -1], [-1, -1]]]
>>> multi_dimensional_list(-1, 2, 3, 2, 2 )  #4D list
[[[[-1, -1], [-1, -1]], [[-1, -1], [-1, -1]], [[-1, -1], [-1, -1]]], [[[-1, -1], [-1, -1]], [[-1, -1], [-1, -1]], [[-1, -1], [-1, -1]]]]

PS 如果您热衷于验证 args 的正确值,即只有自然数,那么您可以在调用此函数之前编写一个包装函数。

  1. 其次,任何多维数组都可以写成一维数组。这意味着您不需要多维数组。以下是索引转换的功能:
def convert_single_to_multi(value, max_dim):
  dim_count = len(max_dim)
  values = [0]*dim_count
  for i in range(dim_count-1, -1, -1): #reverse iteration
    values[i] = value%max_dim[i]
    value /= max_dim[i]
  return values


def convert_multi_to_single(values, max_dim):
  dim_count = len(max_dim)
  value = 0
  length_of_dimension = 1
  for i in range(dim_count-1, -1, -1): #reverse iteration
    value += values[i]*length_of_dimension
    length_of_dimension *= max_dim[i]
  return value

因为,这些函数是互逆的,所以输出如下:

>>> convert_single_to_multi(convert_multi_to_single([1,4,6,7],[23,45,32,14]),[23,45,32,14])
[1, 4, 6, 7]
>>> convert_multi_to_single(convert_single_to_multi(21343,[23,45,32,14]),[23,45,32,14])
21343
  1. 如果您担心性能问题,那么您可以使用一些库,如 pandas、numpy 等。
于 2020-08-31T16:29:51.603 回答
1
n1=np.arange(90).reshape((3,3,-1))
print(n1)
print(n1.shape)
于 2021-03-14T07:08:51.347 回答
0
def n_arr(n, default=0, size=1):
    if n is 0:
        return default

    return [n_arr(n-1, default, size) for _ in range(size)]

arr = n_arr(3, 42, 3)
assert arr[2][2][2], 42
于 2014-01-20T13:43:49.410 回答
-2

如果您坚持将所有内容初始化为空,则需要在内部使用一组额外的括号([[]] 而不是 [],因为这是“包含要复制的 1 个空列表的列表”而不是“包含没有什么可复制的”):

distance=[[[[]]*n]*n]*n
于 2012-05-19T19:49:25.327 回答