0

I am attempting to make an Abelian Sandpile Model (see: Rosetta Code) in Python 3.8, and I have not looked at the provided solution because this is a practice exercise for me. I am getting started with a possible solution, but I am not sure why the following issue is occurring.

I have a 5x5 grid, composed of lists.

 # a list composed of 5 child-lists, each containing five 0's
area = [[0]*5]*5

My first step is to place the sandpile (ie. change one (x, y) pair to a higher number), and I have written this function to accomplish that:

# changes one location to a greater height, takes a one-based (x, y) pair
def make_sandpile(area, loc, height):

    # accommodate for zero-based counting
    loc = list(n-1 for n in loc)

    # translate to x and y
    x, y = loc

    # change the corresponding point in the area
    area[y][x] = height

calling make_sandpile(area, (3, 3), 4) should have the following outcome:

0 0 0 0 0          0 0 0 0 0
0 0 0 0 0          0 0 0 0 0
0 0 0 0 0    ->    0 0 4 0 0
0 0 0 0 0          0 0 0 0 0
0 0 0 0 0          0 0 0 0 0

However, the outcome is as follows:

0 0 0 0 0          0 0 4 0 0
0 0 0 0 0          0 0 4 0 0
0 0 0 0 0    ->    0 0 4 0 0
0 0 0 0 0          0 0 4 0 0
0 0 0 0 0          0 0 4 0 0

What can I do to correct this?

  • The issue is that `[[0]*5]*5` creates a list with 5 references to the same inner list, i.e the list created by `[0]*5` (which itself, is a list with 5 references to the same `int` object..., just that doesn't really matter) – juanpa.arrivillaga Jan 14 '20 at 22:03

1 Answers1

0

Instead of [[0]*5]*5, you should use something like [[0] * 5 for _ in range(5)]. Otherwise, you are just copying the reference to the same list.

Zach Langley
  • 6,776
  • 1
  • 26
  • 25