Назначение ячеек 2-мерной матрицы в Python без numpy

Ниже приведен мой скрипт, который в основном создает нулевую матрицу 12x8, заполненную 0. Затем я хочу заполнить его, один за другим. Итак, скажем, столбец 2 строка 0 должна быть 5. Как мне это сделать? В приведенном ниже примере показано, как я это сделал и неправильный (для моих нужд) вывод:

list_MatrixRow = []
list_Matrix = [] #Not to be confused by what the book calls, optimal alignment score matrix

int_NumbOfColumns = 12
int_NumbOfRows = 8

for i in range (0, int_NumbOfColumns): # Puts Zeros across the first Row
    list_AlignMatrixRow.append(0)
for i in range (0, int_NumbOfRows):
    list_AlignMatrix.append(list_AlignMatrixRow) 
#add the list in another list to make matrix of Zeros
#-------------------THE ACTUAL PROBLEMATIC PART; ABOVE IS FINE(It Works)------------

list_AlignMatrix[2][0] = 5 
# This is what logically makes sense but here is the output 
# which happens but I don't want (there should be all 0s and 
# only one 5 on the cell [2][0]):

[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

4 ответов


каждая строка указывает на один и тот же подсписок. Это результат добавления в подсписок. Поэтому, когда вы изменяете одну строку, вы в конечном итоге изменяете другие.

Я бы сделал так:

ncols = 12
nrows = 8
matrix = [[0] * ncols for i in range(nrows)]
matrix[2][0] = 5 

matrix содержит:

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

в сторону о стиле кодирования: это плохая форма в Python, чтобы включить тип объекта в его имя. Я решил переименовать int_NumbOfColumns as ncols. Если вам нужно что-то более описательное, используйте что-то вроде column_count. Как правило, следует избегать имен mixedCase, в то время как CamelCase обычно используется для имен классов. См.PEP 8 -- руководство по стилю для кода Python дополнительные.

редактировать: поскольку вы упомянули, что вы новичок в Python, здесь немного больше объяснений.

это понимание:

matrix = [[0] * ncols for i in range(nrows)]

он также может быть записан как обычный цикл for:

matrix = []
for i in range(nrows):
    matrix.append([0] * ncols)

каждая запись в list_AlignMatrix ссылочка один и тот же объект. Вам нужно будет создать новый list экземпляру для каждой строки в матрице. Вот иллюстрация того, что происходит:

>>> l = [0]
>>> l2 = [l,l,l]
>>> l2
[[0], [0], [0]]
>>> l2[0][0] = 1
>>> l2
[[1], [1], [1]]

можно использовать id() функция для подтверждения того, что каждая запись в l2 - это ссылка на тот же объект:

>>> [id(x) for x in l2]
[161738316, 161738316, 161738316]

чтобы сделать новые копии списка строк, вы можете переписать свой второй цикл, как это:

for i in range (0, int_NumbOfRows):
    list_AlignMatrix.append(list(list_AlignMatrixRow)) 

на list конструктор создаст копии list_AlignMatrixRow, как показано в следующем примере:

>>> l = range(10)
>>> l2 = list(l)
>>> l == l2
True
>>> l is l2
False

при добавлении list_AlignMatrixRow, это просто добавление ссылки на исходный список, поэтому на самом деле есть один 1-D список, и каждая строка вашей матрицы указывает на него. Чтобы создать новый список, вам нужно создать новый список:

list_AlignMatrix.append(list(list_AlignMatrixRow))

обратите внимание на вызов list, который создает список путем итерации и копирования элементов list_AlignMatrixRow


чтобы создать такую матрицу, в python вы должны использовать list comprihention следующим образом если вы хотите создать строку со всеми 0,

>>> import copy
>>> list_MatrixRow=[0 for i in range(12)]
>>> list_MatrixRow
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

ce затем вы можете создать список в порядке!--4-->

list_Matrix=[[0 для j в диапазоне (12)] для i в диапазоне(8)]

Теперь вы можете редактировать любые элементы

>>> list_Matrix[0][2]=12345
>>> list_Matrix[0][2]
12345
>>> list_Matrix
[[0, 0, 12345, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

Если вы хотите создать матрицу, содержащую весь столбец 5, u может использовать оценка короткого замыкания на понимание списка

>>> list_MatrixRow=[(i==0 and 5 or 0) for i in range(12)]
>>> list_MatrixRow
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> list_Matrix=[list_MatrixRow for i in range(8)]
>>> list_MatrixRow
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> list_Matrix
[[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
>>> list_Matrix[0][0]
5