0

So I'm trying to create an array visualiser with pygame and have run into a strange problem I can't seem to get around,

here's a small portion of code to recreate the issue

def appendto(array):
    temp=[]
    for i in range(3):
        array.append(i)
        temp.append(array)
    return temp

array=[]
print(appendto(array))

When I run this code it shows

[[0, 1, 2], [0, 1, 2], [0, 1, 2]]

I am trying to make the temp array record each change made to the main array, but by the end it seems to have only recorded the final state of the array 3 times.

The only half - solution I have found is to turn the array into a string before appending it, doing

array.append(str(i))

but this will slow down my program significantly as I will then have to turn the string back into an array in order to use it.

please do tell me if I'm doing something wrong

wjandrea
  • 28,235
  • 9
  • 60
  • 81
  • 3
    You add the same array to `temp` three times. The fact that you're modifying the array in between doesn't change the fact that it's the same object, being represented three times. – Green Cloak Guy Jan 06 '22 at 19:47
  • 2
    What you probably intend to do is add a copy of the array at a certain point in time. You can do that by doing either `array.copy()` or `array[:]`. – Green Cloak Guy Jan 06 '22 at 19:48
  • 1
    The first thing you need to understand is that Python assigns object by their reference, *not by value*. Each time you append `array` to `temp`, it is assigning the actual object of `array` into `temp` so in reality you are seeing the same copy of the object 3 times. Just do a `[id(x) for x in temp]` and you'll understand. As @GreenCloakGuy said, if you want the value at the time of the loop, use `array.copy()` instead (which creates a separate copy object of `array` but will not be affected in later iteration of the loop). – r.ook Jan 06 '22 at 19:48
  • Welcome to Stack Overflow! Please take the [tour]. I closed the question because it's practically the same as an existing question. The only difference is that the new reference to the list is in the form of a list element (`temp[i]`) instead of a name (`new_list`). BTW, this is a good first question! though the title could be more specific. For tips, see [ask]. – wjandrea Jan 06 '22 at 20:15
  • BTW, this is a [`list`](https://docs.python.org/3/library/stdtypes.html#lists), not an array. Arrays are different, like [NumPy arrays](https://numpy.org/doc/stable/reference/arrays.html) or [`array.array`](https://docs.python.org/3/library/array.html). – wjandrea Jan 06 '22 at 20:19

1 Answers1

1

I think adding a print() statement in your for loop might help illustrate what is going on.

def appendto(array):
    temp=[]
    for i in range(3):
        array.append(i)
        temp.append(array)
        print(temp)
    return temp

array=[]
print(appendto(array))

This will give you:

[[0]]
[[0, 1], [0, 1]]
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]

We can see that appending items to array cascades though all references to array. To be clear, there is only one array we just now have a list of three items all pointing to it.

What you probably want to do is append a copy.

def appendto(array):
    temp=[]
    for i in range(3):
        array.append(i)
        temp.append(array.copy())
    return temp

array=[]
print(appendto(array))

giving you:

[[0], [0, 1], [0, 1, 2]]
JonSG
  • 10,542
  • 2
  • 25
  • 36