Назначение ячеек 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