Допустим, у вас есть класс Item
и 2 экземпляра o
из Item
:
class Item:
def __init__(self, c):
self.c = c
o = Item('o')
w, h = 3, 3
Выход
for r in map: print([c.c for c in r])
равен
['o', 'o', 'o']
['o', 'o', 'o']
['o', 'o', 'o']
Оператор temp = [o] * w
создает список ссылок на тот же элемент o
, а оператор map = [temp] * h
создает список ссылок на тот же объект списка temp
.
temp = [o] * w
map = [temp] * h
В конце каждый элемент map
ссылается на один-единственный список temp
, а каждый элемент temp
ссылается на один-единственный объект o
. Если содержимое одного внутреннего элемента карты изменяется, то магическим образом кажется, что весь объект меняется. Причина в том, что существует только один объект o
, и все элементы карты ссылаются на один и тот же объект.
Таким образом, вывод:
map[1][1].c = '_'
for r in map: print([c.c for c in r])
равен
['_', '_', '_']
['_', '_', '_']
['_', '_', '_']
Если создается новый экземпляр x
из Item
и изменяется один элемент map
x = Item('x')
map[1][1] = x
for r in map: print([c.c for c in r])
Тогда все элементы в строкеменять. Обратите внимание, что каждый элемент ссылается на один и тот же список temp
. Строк не много, есть только один объект temp
. Если элемент temp
изменяется, то это, кажется, изменения в каждой строке:
['_', 'x', '_']
['_', 'x', '_']
['_', 'x', '_']
Вы должны создать карту, где каждый элемент карты являетсяотдельный экземпляр Item
:
map = [[Item('o') for i in range(w)] for j in range(h)]
Обратите внимание, Item('o')
создает новый экземпляр Item
.
Теперь содержимое элемента можно изменить или назначить новый объектвнутренний элемент, потому что для каждого объекта в каждой строке есть один отдельный объект:
map[1][1].c = 'X'
map[1][0] = Item('x')
for r in map: print([c.c for c in r])
['o', 'o', 'o']
['x', 'X', 'o']
['o', 'o', 'o']