Неправильное заполнение вложенного списка, как исправить?
Столкнулся с проблемой, создаю вложенный список, некий двумерный массив:
tb_pr_impl = [[0]*int(3+len(self.tab_sortirovka))]*int(len(tab_werif) + 2)
print(tb_pr_impl)
tb_pr_impl[1][0] = int(1)
print(tb_pr_impl)
При заполнении определённого индекса вместо заполнения одного элемента, заполняется весь "столбец", с индексом указанном во второй квадратной скобке.
Первая половина это исходный "массив", вторая это то как он заполняется.
Ответы (1 шт):
Создавая массивы умножением, вы создаёте лишь поверхностные копии этого самого массива:
>>> my_list = [[0]*3]*3
>>> my_list
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> id(my_list[0])
67310736
>>> id(my_list[1])
67310736
Как видим, идентификатор у подмассивов совпадает, а это значит, что оба объекта ссылаются на один адрес в памяти. В следствии чего, при изменении одного объекта, изменение затронет и остальные. Чтобы исправить данное недоразумение, можно использовать list comprehension:
>>> my_list = [[0 for _ in range(3)] for _ in range(3)]
>>> my_list
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> id(my_list[0])
67183720
>>> id(my_list[1])
67183680
Теперь, идентификаторы разные. Работает это потому, что вместо копирования уже созданных списков создаются новые.
А если хотите разобраться в теме подробнее, советую поинтересоваться такой темой как "изменяемые и неизменяемые объекты в python".