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)