# Multidimensional arrays

hello. I am just wondering what is difference between m*[n*[1]] and [n*[1] for k in range(m)]
Because this code:

``````m,n = 50,50
grid = [n*[1] for k in range(m)]
screen_size =(600,600)
w=float(screen_size[0])/n
h=float(screen_size[1])/m
def setup():
size(screen_size[0],screen_size[1])
noLoop()

def draw():
draw_grid()

def draw_grid():
x,y=0,0
for row in grid:
for ele in row:
if ele == -1:
fill(0)
else:
fill(255)
rect(x,y,w,h)
x+=w
y+=h
x=0

def get_grid_coordinates(x,y):
return int(y/h), int(x/w)

def mousePressed():
coords = get_grid_coordinates(mouseX,mouseY)
pcoords = get_grid_coordinates(pmouseX,pmouseY)
grid[coords[0]][coords[1]],grid[pcoords[0]][pcoords[1]] = -grid[coords[0]][coords[1]],-grid[pcoords[0]][pcoords[1]]
redraw()
``````

works fine (change color of clicked tile in grid) but this code:

``````m,n = 50,50
grid =  m*[n*[1]]
screen_size =(600,600)
w=float(screen_size[0])/n
h=float(screen_size[1])/m
def setup():
size(screen_size[0],screen_size[1])
noLoop()

def draw():
draw_grid()

def draw_grid():
x,y=0,0
for row in grid:
for ele in row:
if ele == -1:
fill(0)
else:
fill(255)
rect(x,y,w,h)
x+=w
y+=h
x=0

def get_grid_coordinates(x,y):
return int(y/h), int(x/w)

def mousePressed():
coords = get_grid_coordinates(mouseX,mouseY)
pcoords = get_grid_coordinates(pmouseX,pmouseY)
grid[coords[0]][coords[1]],grid[pcoords[0]][pcoords[1]] = -grid[coords[0]][coords[1]],-grid[pcoords[0]][pcoords[1]]
redraw()
``````

changes whole columns.
The strangest is that print([n*[1]] for k in range(m) == m*[n*[1]]) writes True.
I am using processing 4.0b8

I think you should move this to
Processing.py

the Processing thread is for java mode.
And format your code with </> trying to copy this would be a nightmare because the spaces actually are important in pythonâ€¦

I looked it up and python seems to have the same â€śproblemâ€ť than Java.
Have you ever tried copying an array with:

``````array1=array2
``````

You should notice that they are â€ślinkedâ€ť so any action you do with one you also do to the other this is called a deep copy.
Types like numbers or string donâ€™t have deep copies so you can savely use:

``````number1=number2
``````

What python does it duplicates the line-array however it uses a deep copy so any action you perform on one is also performed on the other.

What you are looking for is a shallow copy wich only copies the data there is actually a library for this so you can use:

``````import copy
m=10
n=10
grid=n*[copy.copy(m*[1])]
``````

I donâ€™t know if python mode of Processing has a built in function for this.

Thanks for reply and moving to python mode section.
If I am right in case `m*[n*[1]]` python m times append the same physical list so if one change one of them, the others will be changed too, but in case `[n*[1] for k in range(m)]` for each k, new list of ones is generated.
Am I right?

2 Likes

Yup! Alternatively you can turn the outer dimension a Tuple container:
`tuple(n*[0] for _ in range(m))`

But notice the literal `1` youâ€™re using is immutable.
Thatâ€™s why itâ€™s a good candidate for filling up the entire container.

Otherwise, something mutable like a PVector would cause the same shallow-copy mirror-change bug:
`tuple(n*[PVector()] for _ in range(m))`

2 Likes

BtW, creating a 2d grid container is worth making a custom function for it:

``````def setup():
global grid
grid = createGrid(5) # 5x5 = 0
print grid
exit()

def createGrid(rows, cols = -1, fillValue = 0):
if cols < 0: cols = rows
return tuple([fillValue] * cols for _ in range(rows))
``````
1 Like