Вложенный список меняет свое значение без какого-либо вмешательства - PullRequest
0 голосов
/ 30 марта 2020

Итак, я создал этот класс, который имеет только один вложенный список. По мне [[2,2],[3,3],[4,3]] должен быть выход. Именно так работает назначение предметов в python справа. Вот код:

class A():
    def __init__(self):
        self.a = [[1,1],[2,2],[3,3]]
        self.start()

    def start(self):
        self.do()
        self.a[2][0] += 1
        print(self.a)

    def do(self):
        self.a[0] = self.a[1]
        self.a[1] = self.a[2]

aaa = A()

Но на выходе получилось [[2,2],[4,3],[4,3]]. С последним списком как-то изменился и второй список. И это произошло в строке 8 кода.

Скажите, пожалуйста, что не так, вывод или мои python знания?

1 Ответ

0 голосов
/ 30 марта 2020

Я определю a = [[1,1],[2,2],[3,3]] немного по-другому. Скажем:

b = [1,1]
c = [2,2]
d = [3,3]
a = [b,c,d]

Это то же самое, что и у вас, мы просто дали имена внутреннему списку, чтобы потом было легче следовать.

Можно назвать эти имена ссылки или указатели на места памяти. Если вы не знакомы с этими терминами, посмотрите на "b не содержит [1,1], он просто знает, где находится в памяти программы" .

Хорошо, теперь на self.a[0] = self.a[1]. Эта строка говорит программе: «назначить первый элемент списка a таким же, как второй» * . не скажет " скопировать второй элемент в первый" . Разница в том, что и self.a[0] и self.a[1] указывают на тот же массив [2,2]. Другими словами a = [c,c,d] сейчас.

self.a[1] = self.a[2] делает то же самое, но для разных элементов, поэтому a = [c, d, d]. Пока что все так, как вы ожидаете. Массив равен [[2,2],[3,3],[3,3]], когда вы его печатаете, но проблема в том, что [3,3] здесь тот же массив, к нему можно просто получить доступ двумя элементами self.a.

Теперь давайте рассмотрим self.a[2][0] += 1 шаг за шагом:

  1. путем вызова self.a[2] мы получаем доступ к указателю к массиву d = [3,3]
  2. после этой логики c, высказывание self.a[2][0] - это то же самое, что выражение d[0]
  3. , поскольку мы увеличили d[0], и оба self.a[1] и self[2] указывают до d, оба self.a[1][0] и self.a[2][0] изменились.

Другой способ взглянуть на это состоит в том, что ваш код эквивалентен:

class A():
    def __init__(self):
        self.b = [1,1]
        self.c = [2,2]
        self.d = [3,3]
        self.a = [self.b, self.c, self.d]
        self.a[0] = self.c
        self.a[1] = self.d
        self.d[0] += 1
        print(self.a)

aaa = A()

Массив в self.a не является массивом который содержит массивы, это просто массив, содержащий переменных, которые знают, где находятся эти массивы (т.е. указатели или ссылки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...