0

So basically I have a main 2d array called grid filled with cell objects and I create a clone of this array called gridN for later use but when I set all of gridN's density to 0 the main grid's density is set to 0 aswell. This can be seen because the print on the last couple of lines returns 0.

class cell:
    x = 0
    y = 0

    den = 0

    velX = 0
    velY = 0

width = 10
height = 10
grid = []


for i in range(width):
    grid.append([])
    for j in range(height):
        grid[i].append(cell())
        grid[i][j].x = i
        grid[i][j].y = j


def diffuse(k,grid):
    gridN = list(grid)
    
    for i in range(width):
        gridN.append([])
        for j in range(height):
            gridN[i].append(cell())
            gridN[i][j].den = 0
    print(gridN[0][0].den)
    
grid[0][0].den = 100
diffuse(0.5,grid)

I tried adding some things to stop both arrays from accessing the same memory like: list() [:] .copy()

Deo Power
  • 3
  • 1

2 Answers2

0

Maybe this helps you:

import copy

def diffuse(k, grid):
    gridN = [[copy.copy(cell_obj) for cell_obj in line] for line in grid]
    ...

With list(grid) you create a new list of the inner lists. Those are stored as references and not as values. When you try to copy them you also have to make copies of other complex objects that are saved as references. In this case your own cell class.

When a list or cell object is saved in another outer list the reference is copied and points to the same data. So your values are changed in both

PS: I think you don't intend to start with i from the beginning again in the for loop inside your function. gridN isn't empty and i starts at 0. So gridN[i] shouldn't access the new item

h-c
  • 34
  • 4
0

Simple way

Use "deepcopy" method of "copy" module

import copy

def diffuse(k, grid):
    gridN = copy.deepcopy(grid)
    ...

More logical way (in my opinion)

Create a Grid class with inner Cell class and clone method which you can use in different functions.

class Grid:
    ''' Simple Grid class '''
    class Cell:
        ''' Even more simple cell class '''
        x = 0
        y = 0
        den = 0
        velX = 0
        velY = 0

        def __repr__(self) -> str:
            ''' Returns density of cell for representation '''
            return self.den.__str__()


    def __init__(self, width:int=10, height:int=10) -> None:
        self.arr = self._build_arr(width, height)


    def _build_arr(self, width:int, height:int) -> None:
        ''' Creates array with given width and height '''
        new_arr = []
        for h in range(height):
            new_arr.append([])
            for w in range(width):
                new_arr[h].append(self.Cell())
        return new_arr
    

    def clone(self):
        ''' Returns Grid object with the same array of cells. '''
        new_grid_obj = Grid()
        new_grid_obj.arr = self.arr.copy()
        return new_grid_obj


def diffuse(k:int, grid:Grid) -> None:
    gridN = grid.clone() # gridN is now a new object with the same self.arr as grid
    ... # Do what you want to do with gridN object.


# initializing main grid object
grid = Grid(width=10, height=10)

diffuse(k=5, grid=grid)