Двумерный массив Python - изменение элемента

У меня есть этот двумерный массив 7x7:

l=[[1, 1, 1, 1, 1, 1, 1],
  [1, 0, 2, 0, 0, 0, 1],
  [1, 0, 0, 0, 0, 0, 1],
  [1, 0, 0, 0, 0, 0, 1],
  [1, 0, 0, 0, 0, 0, 1],
  [1, 0, 0, 0, 0, 0, 1],
  [1, 1, 1, 1, 1, 1, 1]]

Как вы можете видеть, l [1] [2] = 2. Когда я печатаю его, элемент печатается правильно. Здесь нет проблем. Но когда я пытаюсь изменить его с "2" на "3" или на любой другой номер, программа меняет все элементы в этом столбце (в этом случае третий столбец), за исключением первого и последнего. Например, если я набираю этот код:

l[1][2]=5

а затем напечатайте двумерный массив, я получаю следующее:

l=[[1, 1, 1, 1, 1, 1, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 0, 5, 0, 0, 0, 1],
  [1, 1, 1, 1, 1, 1, 1]]

Это происходит с каждым выбранным мной элементом. Вместо того, чтобы изменять только этот элемент, он меняет весь столбец. Кто-нибудь знает, что может быть проблемой? Спасибо!

Ответ 1

Я заберу этот удар, даже если поведение, которое вы описываете (как вы описали), невозможно.

Если вы создаете список, вам нужно убедиться, что каждый подсписок - это другой список. Рассмотрим:

a = []
b = [a, a]

Здесь я создал список, в котором оба подписок - это тот же самый список. Если я изменю один, он появится в обоих. например:.

>>> a = []
>>> b = [a, a]
>>> b[0].append(1)
>>> b
[[1], [1]]

вы будете часто видеть это поведение с инициализацией списка с помощью оператора *:

a = [[None]*7]*7

например.

>>> a = [[None]*7]*7
>>> a
[[None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None]]
>>> a[0][1] = 3
>>> a
[[None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None], [None, 3, None, None, None, None, None]]

Исправить не следует использовать * 7 во внешнем списке (внутренний список в порядке, так как None является неизменным):

a = [[None]*7 for _ in range(7)]

например:.

>>> a = [[None]*7 for _ in range(7)]
>>> a[0][1] = 3
>>> a
[[None, 3, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None], [None, None, None, None, None, None, None]]

Ответ 2

Вы неправильно настроили свой список.

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

Если вы покажете код, который вы используете для построения списка, я могу показать вам, как его исправить.

В качестве альтернативы

l = [sublist[:] for sublist in l]

перед тем, как вы начнете изменять списки, все их разделите на новые списки