The crucial thing to understand is that list
objects do not have rows and columns. List objects are ordered, heterogeneous sequences of objects. When you do:
def createGamePlan(size, sign):
gPlan = []
row = [sign]*size
for i in range(size):
gPlan.append(row) # appends the SAME object
return gPlan
So, consider the following:
>>> a = ['foo']
>>> bar = []
>>> for _ in range(4):
... bar.append(a)
...
>>> [id(x) for x in bar]
[4534044744, 4534044744, 4534044744, 4534044744]
The objects are all the same!
>>> bar[0].append('baz')
>>> bar
[['foo', 'baz'], ['foo', 'baz'], ['foo', 'baz'], ['foo', 'baz']]
You create a list that contains the same object many times. A solution? Append a copy.
def createGamePlan(size, sign):
gPlan = []
row = [sign]*size
for i in range(size):
gPlan.append(row.copy()) # appends a NEW object
return gPlan
Be careful, though, because .copy
only makes a shallow copy. Consider:
>>> row = [['foo'], ['bar']]
>>> grid = []
>>> for _ in range(5):
... grid.append(row.copy())
...
>>> grid
[[['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']]]
OK, swell! these are all independant objects!:
>>> [id(x) for x in grid]
[4534044616, 4534135432, 4534135560, 4534135176, 4534135688]
So... this should work fine, no?
>>> grid[0][0].append('baz')
>>> grid
[[['foo', 'baz'], ['bar']], [['foo', 'baz'], ['bar']], [['foo', 'baz'], ['bar']], [['foo', 'baz'], ['bar']], [['foo', 'baz'], ['bar']]]
What's going on? Well, a shallow copy created new lists, but not new sublists, i.e., it didn't copy any elements contained in the elements:
>>> [id(x) for row in grid for x in row]
[4534135048, 4534135112, 4534135048, 4534135112, 4534135048, 4534135112, 4534135048, 4534135112, 4534135048, 4534135112]
>>>
For that, you want a deepcopy:
>>> import copy
>>> row = [['foo'], ['bar']]
>>> grid = []
>>> for _ in range(5):
... grid.append(copy.deepcopy(row))
...
>>> grid
[[['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']]]
>>> [id(x) for row in grid for x in row]
[4534135432, 4534135368, 4534135176, 4534135880, 4534136328, 4534161928, 4534135112, 4534162120, 4534162248, 4534162184]
>>> grid[0][0].append('baz')
>>> grid
[[['foo', 'baz'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']]]
>>>