19

在 Python 中,我想要一种直观的方式来创建 3 维列表。

我想要一个 (n by n) 列表。所以对于 n = 4 它应该是:

x = [[[],[],[],[]],[[],[],[],[]],[[],[],[],[]],[[],[],[],[]]]

我试过使用:

y = [n*[n*[]]]    
y = [[[]]* n for i in range(n)]

两者似乎都在创建参考的副本。我也尝试过简单地应用列表生成器,但收效甚微:

y = [[[]* n for i in range(n)]* n for i in range(n)]
y = [[[]* n for i in range(1)]* n for i in range(n)]

我还尝试使用循环迭代地构建数组,但没有成功。我也试过这个:

y = []
for i in range(0,n):
    y.append([[]*n for i in range(n)])

有没有更简单或更直观的方法来做到这一点?

4

13 回答 13

22

我认为您的列表理解版本非常接近工作。您不需要进行任何列表乘法(无论如何它都不适用于空列表)。这是一个工作版本:

>>> y = [[[] for i in range(n)] for i in range(n)]
>>> print y
[[[], [], [], []], [[], [], [], []], [[], [], [], []], [[], [], [], []]]
于 2012-11-19T05:11:49.267 回答
6

看起来最简单的方法如下:

def create_empty_array_of_shape(shape):
    if shape: return [create_empty_array_of_shape(shape[1:]) for i in xrange(shape[0])]

这对我有用

于 2013-10-03T05:04:24.857 回答
3

我找到了这个:

Matrix = [[0 for x in xrange(5)] for x in xrange(5)]

您现在可以将项目添加到列表中:

Matrix[0][0] = 1
Matrix[4][0] = 5

print Matrix[0][0] # prints 1
print Matrix[4][0] # prints 5

从这里:如何在python中定义二维数组

于 2012-11-19T05:07:53.380 回答
3

一个非常简单优雅的方法是:

a = [([0] * 5) for i in range(5)]
a
[[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]]
于 2016-04-08T11:40:21.000 回答
3

在 Python 中,我做了一个小工厂方法来创建每个维度上的可变维度和可变大小的列表:

def create_n_dimensional_matrix(self, n):
  dimensions = len(n)
  if (dimensions == 1): 
    return [0 for i in range(n[0])]

  if (dimensions == 2): 
    return [[0 for i in range(n[0])] for j in range(n[1])]

  if (dimensions == 3): 
    return [[[0 for i in range(n[0])] for j in range(n[1])] for k in range(n[2])]

  if (dimensions == 4): 
    return [[[[0 for i in range(n[0])] for j in range(n[1])] for k in range(n[2])] for l in range(n[3])]

像这样运行它:

print(str(k.create_n_dimensional_matrix([2,3])))
print(str(k.create_n_dimensional_matrix([3,2])))
print(str(k.create_n_dimensional_matrix([1,2,3])))
print(str(k.create_n_dimensional_matrix([3,2,1])))
print(str(k.create_n_dimensional_matrix([2,3,4,5])))
print(str(k.create_n_dimensional_matrix([5,4,3,2])))    

哪个打印:

  1. 二维列表 (2x3), (3x2)
  2. 三维列表 (1x2x3),(3x2x1)
  3. 四维列表 (2x3x4x5),(5x4x3x2)

    [[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], [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], [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, 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, 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, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]]
    
于 2016-04-18T19:51:27.357 回答
2

这个怎么样:

class MultiDimList(object):
    def __init__(self, shape):
        self.shape = shape
        self.L = self._createMultiDimList(shape)
    def get(self, ind):
        if(len(ind) != len(self.shape)): raise IndexError()
        return self._get(self.L, ind)
    def set(self, ind, val):
        if(len(ind) != len(self.shape)): raise IndexError()
        return self._set(self.L, ind, val)
    def _get(self, L, ind):
        return self._get(L[ind[0]], ind[1:]) if len(ind) > 1 else L[ind[0]]
    def _set(self, L, ind, val):
        if(len(ind) > 1): 
            self._set(L[ind[0]], ind[1:], val) 
        else: 
            L[ind[0]] = val
    def _createMultiDimList(self, shape):
        return [self._createMultiDimList(shape[1:]) if len(shape) > 1 else None for _ in range(shape[0])]
    def __repr__(self):
        return repr(self.L)

然后您可以按如下方式使用它

L = MultiDimList((3,4,5)) # creates a 3x4x5 list
L.set((0,0,0), 1)
L.get((0,0,0))
于 2013-09-11T15:12:05.527 回答
2
import copy
dimensions = 2, 3, 4
z = 0
genList = lambda size,value: [copy.deepcopy(value) for i in range(size)]
for i in dimensions: z = genList(i, z)
于 2018-09-19T00:12:36.587 回答
1

这是一个将为您提供一个 N 维“矩阵”,其中填充了可复制对象的副本。

编辑:这是对 pterodragon 原始答案的轻微修改,我更喜欢 user2114402 的可读性较差的答案。事实上,在文档字符串之外,与 pterodragon 解决方案的唯一区别是我明确使用了维度大小列表,而不是让用户将它们作为参数传递。

import copy

    def instantiate_mdl(dim_maxes, base=0):
        """ Instantiate multi-dimensional list, that is a list of list of list ...

        Arguments:
            dim_maxes (list[int]): a list of dimension sizes, for example 
            [2, 4] represents a matrix (represented by lists) of 2 rows and 
            4 columns.     

            base (object): an optional argument indicating the object copies
            of which will reside at the lowest level in the datastructure.
        Returns:
            base (list[base]): a multi-dimensional list of lists structure,
            which is filled with clones of the base parameter.
        """
        for dim_max in reversed(dim_maxes):
            base = [copy.deepcopy(base) for i in range(dim_max)]
        return base

data = instantiate_mdl([3, 5])
data[0][0] = 99999
data[1][1] = 88888
data[2][4] = 77777

for r in data:
    print(r)

>>> # Output
>>> [99999, 0, 0, 0, 0]
>>> [0, 88888, 0, 0, 0]
>>> [0, 0, 0, 0, 77777]
于 2018-12-01T03:28:52.903 回答
1

我很惊讶没有人试图设计一种通用的方法来做到这一点。在这里查看我的答案:https ://stackoverflow.com/a/33460217/5256940

import copy

def ndlist(init, *args):  # python 2 doesn't have kwarg after *args
    dp = init
    for x in reversed(args):
        dp = [copy.deepcopy(dp) for _ in xrange(x)] # Python 2 xrange
    return dp

l = ndlist(0, 1, 2, 3, 4) # 4 dimensional list initialized with 0's
l[0][1][2][3] = 1

编辑:基于 user2114402 的答案:添加了默认值参数

def ndlist(s, v):
    return [ndlist(s[1:], v) for i in xrange(s[0])] if s else v
于 2015-11-01T08:00:43.080 回答
0

Here is a losution that works for any number of dimention :

def multi_dimensional_list(dimensions, filling=None):
    if len(dimensions) == 1:
        return [filling] * dimensions[0]
    else:
        return [
            multi_dimensional_list(dimensions[1:], filling)
            for _ in range(dimensions[0])
        ]


print(multi_dimensional_list([2, 3, 4], 0))
"""
    output :
    [
        [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
    ]
"""
于 2021-05-28T21:39:57.483 回答
0

这是一种更通用的方法。

def ndlist(shape, dtype=list):
    t = '%s for v%d in xrange(shape[%d])'
    cmd = [t % ('%s', i + 1, i) for i in xrange(len(shape))]
    cmd[-1] = cmd[-1] % str(dtype())
    for i in range(len(cmd) - 1)[::-1]:
        cmd[i] = cmd[i] % ('[' + cmd[i + 1]  + ']')
    return eval('[' + cmd[0] + ']')

list_4d = ndlist((2, 3, 4))
list_3d_int = ndlist((2, 3, 4), dtype=int)

print list_4d
print list_3d_int

结果:

[[[[], [], [], []], [[], [], [], []], [[], [], [], []]], [[[], [], [], []], [[], [], [], []], [[], [], [], []]]]
[[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]
于 2017-03-01T21:20:51.583 回答
0

您还可以使用 append 方法构建具有不同长度行的二维列表。例如

sf_gcov_cell = []
sf_gcov_cell.append(['r1_c1', 'r2_c2_', 'r3_c3__', 'r4_c4'])
sf_gcov_cell.append(['r2_c1', 'r2_c2'])
sf_gcov_cell.append(['r3_c1', 'r3_c2___', 'r3_c3_'])
print(sf_gcov_cell)

结果:

[['r1_c1', 'r2_c2_', 'r3_c3__', 'r4_c4'], ['r2_c1', 'r2_c2'], ['r3_c1', 'r3_c2___', 'r3_c3_']]
于 2019-10-10T14:26:59.603 回答
0

只需使用一个简单的递归函数,它会不断地将新数组附加到自身内部的初始化数组中。

#  Counts the maximum amount of dimensions in an array
def dcounter(array: list, total = 1):

    for arr in array:
        return dcounter(arr, total + 1)

    return total


#  Create array with specified amount of dimensions
def nd_array(dimensions = 1, array = list(), i = 0):

    if dimensions > 1:
        array.append([])
        nd_array(dimensions - 1, array[i])
        
    return array


#  Create a 5D array
array = nd_array(5)
print(array) #  =>  "[[[[[]]]]]"


#  Get the maximum amount of dimensions in the array
amount = dcounter(array)
print(amount) #  =>  "5"

如果您想指定每个维度的大小,每个维度内的数组数量,那么您可以修改nd_array为这样做。

于 2021-03-25T22:05:25.617 回答