Python中的二维列表数组
我想创建一个二维矩阵,让每个单元格里面都包含一个字符串列表。
矩阵的大小在创建之前就已经确定了,我需要能够从一开始就访问到任何元素(而不是动态填充矩阵)。我觉得需要提前分配一些空间。
比如,我想要一个2X2的矩阵:
[['A','B'] ['C'];
['d'] ['e','f','f']]
并且支持传统的矩阵访问操作,比如
(Matrix[2][2]).extend('d')
或者
tmp = Matrix[2][2]
tmp.extend('d')
Matrix[2][2] = tmp
来操作单元格的内容。
在Python中怎么实现这个呢?
6 个回答
首先,你描述的其实是一个三维矩阵,因为每个“单元格”都有一个维度,你可以通过 matrix[i][j][k]
来访问第 i
行第 j
列的第 k
个元素。
不过,如果你想要预先创建一个 2X2 的矩阵,并且每个单元都初始化为空列表,这个函数可以帮你做到:
def alloc_matrix2d(W, H):
""" Pre-allocate a 2D matrix of empty lists. """
return [ [ [] for i in range(W) ] for j in range(H) ]
但是你可能会觉得它不工作,因为我注意到你说你想要一个这样的 2X2 矩阵:
[
[
['A','B'], ['C']
],
[
['d'], ['e','f','f']
]
]
并且希望能用“传统的矩阵访问操作”来处理它:
(Matrix[2][2]).extend('d')
问题是,即使是你展示的那个矩阵,这种方式也不行,对于预先分配的 2X2 矩阵也是如此,因为在这两种情况下,行和列的维度都超出了范围。在 Python 中,所有的序列都是从零开始编号的,所以一个有两行两列的矩阵的有效索引是 [0][0]
、[0][1]
、[1][0]
和 [1][1]
(忽略可能的负索引,因为它们在 Python 中有特殊含义)。所以使用 Matrix[2][2]
是在尝试访问矩阵的第三行的第三列,而这并不存在,即使是一个预先分配的 2X2 矩阵也没有这个。
如果你把那个语句改成使用有效的索引值对(并去掉不必要的括号),一切就会好起来:
Matrix[1][1].extend('d')
这样就不会引发 IndexError
,而是会让这个 2X2 矩阵变成:
[
[
['A', 'B'], ['C']
],
[
['d'], ['e', 'f', 'f', 'd']
]
]
额外工具
你没有要求这个,但我写了一个方便的函数,可以帮助打印出任意大小的 2D 矩阵,支持任何类型(用嵌套的 lists
表示):
def repr_matrix2d(name, matrix):
lines = ['{} = ['.format(name)]
rows = []
for row in range(len(matrix)):
itemreprs = [repr(matrix[row][col]) for col in range(len(matrix[row]))]
rows.append('\n [\n {}\n ]'.format(', '.join(itemreprs)))
lines.append('{}\n]'.format(','.join(rows)))
return ''.join(lines)
希望这对你有帮助。
你可以用最基本的方法来实现:
matrix = [
[["s1","s2"], ["s3"]],
[["s4"], ["s5"]]
]
或者你也可以用一种更通用的方法来做
from collections import defaultdict
m = defaultdict(lambda : defaultdict(list))
m[0][0].append('s1')
在使用defaultdict的情况下,你可以使用一个任意大小的矩阵,所有的元素都是数组,可以根据需要进行操作。
就像你写的那样:
>>> matrix = [["str1", "str2"], ["str3"], ["str4", "str5"]]
>>> matrix
[['str1', 'str2'], ['str3'], ['str4', 'str5']]
>>> matrix[0][1]
'str2'
>>> matrix[0][1] += "someText"
>>> matrix
[['str1', 'str2someText'], ['str3'], ['str4', 'str5']]
>>> matrix[0].extend(["str6"])
>>> matrix[0]
['str1', 'str2someText', 'str6']
可以把二维矩阵想象成一个列表里面又包含了很多个列表。其他操作也都能正常工作,比如:
>>> matrix[0].append('value')
>>> matrix[0]
[0, 0, 0, 0, 0, 'value']
>>> matrix[0].pop()
'value'
>>>