The Objective
I need to take an array with data that can be displayed in 2 dimensions, and paste it over any part of a 2D array as if it were an image. This function would be similar to the Python library Pillow’s paste function.
Example
Say I have a 2D array with a size of 5×5, with a default value of 0.
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
]
And I have an average array with the length of 4, which can be assembled into 2×2 form.
[0, 1,
1, 1]
With this, I need a function to, as if these arrays were images, ‘paste’ the second over the first. With a position (anchored from the top left) of (1,2), it would result in this 2D array.
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 0, 0, 0]
]
My Attempt
Here is my attempt at creating the Python code.
class Indexed:
def __init__(self, x, y):
self.array = [[0]*x]*y
self.dimensions = (x, y)
def writeImage(self, indexed, x, y, width, height):
index = 0
for ArrayY in range(height):
self.array[ArrayY] = [0]*self.dimensions[0]
for ArrayX in range(width):
self.array[1 + ArrayY][x + ArrayX] = indexed[index]
index+=1
Test = Indexed(12,12)
Test.writeImage(
[
0,0,7,0,0,7,0,0,
0,0,7,0,0,7,0,0,
0,0,7,0,0,7,0,0,
7,0,0,0,0,0,0,7,
7,7,7,7,7,7,7,7
],
0,0, 8,5
)
print(Test.array)
The Problem
If you attempt to run the code above, you will see that it outputs this result.
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0],
[7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0],
[7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0],
[7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0],
[7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0],
[7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0],
[7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0]
]
This is the intended result.
[
[0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 0, 0],
[7, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0],
[7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
I’ve tinkered with it a lot and haven’t found any answers online for why these arrays work the way they do here.
Any help is greatly appreciated.
Advertisement
Answer
When you initialise self.array [[0]*x]*y
. The [0]*x is only shallow copied (reference only) y times, which means all of the row is basically the same array.
Since it is the same array, it’s final value would be the last row, i.e. 7,7,7,7,7,7,7,7
. Thats why the one updated is such value.
Also noted the index is incorrect in the writeImage
from pprint import pprint
class Indexed:
def __init__(self, x, y):
self.array = [0]*y
for i in range(y):
self.array[i] = [0]*x
self.dimensions = (x, y)
def writeImage(self, indexed, x, y, width, height):
for ArrayY in range(height):
for ArrayX in range(width):
index = (ArrayY * width) + ArrayX
self.array[y + ArrayY][x + ArrayX] = indexed[index]
Test = Indexed(12,12)
Test.writeImage(
[
0,0,7,0,0,7,0,0,
0,0,7,0,0,7,0,0,
0,0,7,0,0,7,0,0,
7,0,0,0,0,0,0,7,
7,7,7,7,7,7,7,7
],
0,0, 8,5
)
pprint(Test.array)