Skip to content
Advertisement

How would I go about pasting an array over a 2D array?

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)
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement