← Все вопросы

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

Задан 2 месяца назад7 просмотров1 ответ
0

Создал список так: matrix = [[0] * 3] * 3 matrix[0][1] = 5 print(matrix) # Выводит [[0, 5, 0], [0, 5, 0], [0, 5, 0]] — почему изменились все строки? Ожидал увидеть [[0, 5, 0], [0, 0, 0], [0, 0, 0]], но изменился второй элемент в каждой строке. Почему оператор * ведёт себя так странно с вложенными списками? Как правильно создать независимые строки матрицы? Ведь если я создаю простой список [0] * 5, то изменения работают корректно.

1 ответ

0

классика) * не копирует внутренний список — он копирует ссылку на него. то есть [[0]*3]*3 создаёт не три разные строки, а три имени для ОДНОГО и того же списка [0, 0, 0]. меняешь элемент через любую строку — меняется единственный реальный список, поэтому «поменялось во всех».

проверить легко:

matrix = [[0]*3]*3
print(matrix[0] is matrix[1])  # True — это один и тот же объект

а [0]*5 ведёт себя нормально, потому что там копируются числа, а числа неизменяемы: элемент можно только заменить целиком, соседей это не заденет. проблема именно с вложенными изменяемыми объектами — списками, словарями.

как правильно — собирать через генератор, чтобы каждая строка создавалась заново:

matrix = [[0]*3 for _ in range(3)]
matrix[0][1] = 5
print(matrix)  # [[0, 5, 0], [0, 0, 0], [0, 0, 0]]

тут [0]*3 внутри — ок, потому что 0 неизменяем. а внешний список собираем через for, и каждая строка получается своим отдельным объектом

Ваш ответ

, чтобы ответить на вопрос.