2d массив списков в Python - PullRequest
       54

2d массив списков в Python

7 голосов
/ 31 октября 2010

Я пытаюсь создать 2-мерную матрицу, чтобы каждая ячейка содержала список строк. Размеры матрицы известны до создания, и мне нужно иметь доступ к любому элементу с самого начала (без динамического заполнения матрицы). => Я думаю, что нужно какое-то предварительное распределение пространства.

Например, я хотел бы иметь матрицу 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?

Ответы [ 5 ]

9 голосов
/ 31 октября 2010

Как вы и написали:

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

Просто представьте, что 2D-матрица - это список списков.Другие операции также работают нормально, например,

>>> matrix[0].append('value')
>>> matrix[0]
[0, 0, 0, 0, 0, 'value']
>>> matrix[0].pop()
'value'
>>> 
4 голосов
/ 31 октября 2010

Прежде всего, то, что вы описываете, на самом деле является трехмерной матрицей, поскольку каждая «ячейка» также имеет измерение, элемент kth столбца jth которого в строке ith может быть доступен через 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] (игнорируя возможные отрицательные индексы, которые имеют особое значение в Python). Таким образом, использование Matrix[2][2] является попыткой получить доступ к третьему столбцу третьей строки матрицы, которая не существует и не будет даже в предварительно выделенном с размерами 2X2 ,

Все было бы хорошо, если бы вы изменили этот оператор на что-то вроде этого, используя одну из допустимых пар значений индекса (и без лишних скобок):

Matrix[1][1].extend('d')

, поскольку не поднимает IndexError и вместо этого приводит к матрице 2X2:

[
    [
        ['A', 'B'], ['C']
    ],
    [
        ['d'], ['e', 'f', 'f', 'd']
    ]
]

Бонусная утилита Вы не просили об этом, но вот удобная функция, которую я написал, чтобы помочь распечатать произвольные по размеру двумерные матрицы любого типа (представленные как вложенные 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)

Надеюсь, это поможет.

4 голосов
/ 31 октября 2010

Вы можете сделать это с основными:

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

или вы можете сделать это очень обобщенно

from collections import defaultdict
m = defaultdict(lambda  : defaultdict(list))
m[0][0].append('s1')

В случае defaultdict у вас есть произвольная матрица, которую вы можете использовать, любой размер и все элементы являются массивами, чтобы манипулировать ими соответственно.

1 голос
/ 31 октября 2010

Один из вариантов - написать собственный класс, в котором вы перегружаете оператор [].Посмотрите на это здесь: http://www.penzilla.net/tutorials/python/classes/.Доступ к 2-му элементу в 1-ом равен y * rowSize + x.Расширение элементов путем написания функции добавления, которая будет использовать время добавления строки.

Если вы хотите создать 2-мерную матрицу и вам нужно предварительно выделить ее, вы можете сделать следующее:

x,y = 3,3
A = [ [None]*x for i in range(y) ]

Вы можете заменить None на требуемое значение.И вы можете использовать .extend для добавления дополнительных значений.

0 голосов
/ 10 марта 2017

Эй, ребята, не уверены, полезно это или нет, но именно так я сгенерировал 2d список с помощью python3.4, надеюсь, это полезно

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)
...