Python中的二维列表数组

8
我正在尝试创建一个二维矩阵,使每个单元格包含一个字符串列表。
在创建之前已知矩阵的维度,并且需要从一开始就可以访问任何元素(不是动态填充矩阵)。我认为需要进行某种形式的空间预分配。
例如,我想要一个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中操作单元格内容?

要实现这个目标,您可以使用以下方法:


1
顺便说一句,我认为你应该从基础的Python教程开始学起,一旦你掌握了Python的基础知识,你就能理解这个问题了。 - Lie Ryan
6个回答

10

就像你写的那样:

>>> 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'
>>> 

5

你可以使用基本方式来完成:

matrix = [
   [["s1","s2"], ["s3"]],
   [["s4"], ["s5"]]
]

或者你可以非常通用地完成它。
from collections import defaultdict
m = defaultdict(lambda  : defaultdict(list))
m[0][0].append('s1')

在defaultdict情况下,您可以使用任意大小的矩阵,并且所有元素都是数组,可以相应地进行操作。

1
m = defaultdict(lambda: defaultdict(list)) - 对于我的目的来说是最好的! - Nik
你能解释一下 m = defaultdict(lambda : defaultdict(list)) 吗? - Bheid
defaultdict() 接受一个函数作为参数来创建元素,使用 lambda:defaultdict(list) 创建了一个不带参数并返回列表的函数。请参阅 https://docs.python.org/2/library/collections.html#defaultdict-objects。 - koblas

4

首先,你描述的实际上是一个三维矩阵,因为每个“单元格”还有一个维度,其第i行的第j列的第k个元素可以通过matrix[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](忽略可能具有特殊含义的负索引)。因此,使用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)

希望这能帮到你。

2
一种选项是编写自己的类,其中重载[]运算符。可以在此处查看:http://www.penzilla.net/tutorials/python/classes/。 访问1d中的2d元素为y * rowSize + x。通过编写一个append函数来扩展元素,该函数将使用append rowSize次数。
如果您想创建一个2d矩阵并需要预先分配,则可以执行以下操作:
x,y = 3,3
A = [ [None]*x for i in range(y) ]

您可以将None替换为您想要的值。您还可以使用.extend添加其他值。


只是想指出,由于xy都是3,因此这将分配一个3X3的二维矩阵。 - martineau
如果你需要一个三维矩阵,这个代码可以帮到你:[[ [0]*x for i in range(y) ] for j in range(z)] - Metagrapher

1
这里有一个扩展二维列表的最小示例:
my_list = [ [  [1] for x in range(4) ] for j in range(2) ]
print('initial list is ', my_list)
my_list[0][1].append(9)
print('list after extension is ', my_list)

结果如下:

initial list is  [[[1], [1], [1], [1]], [[1], [1], [1], [1]]]
list after extension is  [[[1], [1, 9], [1], [1]], [[1], [1], [1], [1]]]


0

大家好,不确定这是否有帮助,但这是我如何使用Python3.4生成2D列表的方法,希望这对你有所帮助。

list=[]
list1=[]
list2=[]
list3=[]
answer1='yes'
answer2='yes'
answer3='yes'

while answer1=='yes':
    item1=input("Please input a list element for your first list:")
    answer1=input("Do you want to continue:")
    list1.append(item1)

while answer2=='yes':
    item2=input("Please input a list element for your second list:")
    answer2=input("Do you want to continue:")
    list2.append(item2)

while answer3=='yes':
    item3=input("Please input a list element for your third list:")
    answer3=input("Do you want to continue:")
    list3.append(item3)

list.append(list1)
list.append(list2)
list.append(list3)

print(list)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接