Есть некоторые тонкости в том, как оператор умножения *
работает со списками в python.
В более общем плане, существуют различия в его эффектах при применении к неизменным объектам, таким как целые числа или строки, и к тому, как они применяются при применении к mutable объектам, таким как списки и словари. 1008 *
Это может прояснить проблему:
>>> l = [0] * 3 #a list of immutable integers
>>> l
[0, 0, 0]
>>> l[0] = 1
>>> l
[1, 0, 0]
>>> l = [[0]] * 3 #a list of mutable lists
>>> l
[[0], [0], [0]]
>>> l[0][0] = 1
>>> l
[[1], [1], [1]]
РЕДАКТИРОВАТЬ (спасибо @lazyr в комментариях) В обоих случаях оператор *
создает список объектов с одинаковой идентичностью (адресом памяти), поэтому каждое число (и каждый список) в массиве - это на самом деле один и тот же объект, однако неизменяемые типы нельзя изменять, а только заменять, поэтому при попытке назначить новое значение целочисленному массиву вы фактически замените весь объект, хотя это не так. случай со списками. На основании предыдущего примера (имейте в виду, что функция id
возвращает адрес памяти объекта):
>>> m = [1] * 3
>>> id(m[0])
39356344
>>> id(m[1])
39356344
>>> m[1] = 2
>>> id(m[1])
39356320 # new memory addres = different object!
>>> m = [[1]] * 3
>>> id(m[0])
40275408
>>> id(m[1])
40275408
>>> m[1][0] = 2
>>> id(m[1])
40275408 # same memory address = still the same object!
Итак, в вашем случае возможный обходной путь - инициализация матрицы следующим образом:
>>> matrix = [[0 for i in range(3)] for j in range(2)]
>>> matrix
[[0, 0, 0], [0, 0, 0]]
>>> matrix[0][2] = 1
>>> matrix
[[0, 1, 0], [0, 0, 0]]
Альтернативным, более радикальным способом было бы вообще переключиться на numpy , который быстрее и продуман с нуля для чрезвычайно быстрой манипуляции с матричными и многомерными векторами, но его также сложнее использовать.
НТН!