0
array = []
matrix = []

x = 0

while(x < 3):
    array.append(".")
    x += 1

x = 0

while(x < 3):
    matrix.append(array)
    x += 1

output:

[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']]

when I try to change for instance matrix[0][1] to become "x" it changes the position in all the inner arrays. Can someone explain why?

example:

matrix[0][1] = "x"

output:

[['.', 'x', '.'], ['.', 'x', '.'], ['.', 'x', '.']]
Brown Bear
  • 19,655
  • 10
  • 58
  • 76
gg4323412
  • 51
  • 5

2 Answers2

4

in your second while loop you have to append a copy of the array varibale

while(x < 3):
    matrix.append(array.copy())
    x += 1

otherwise, you will have the same list 3 times

matrix[0][1] = 'x'
print(matrix)

output:

[['.', 'x', '.'], ['.', '.', '.'], ['.', '.', '.']]
kederrac
  • 16,819
  • 6
  • 32
  • 55
-1

The reason ['.', 'x', '.'] appears in each element is because your array is a list object. That means anytime you set something equal to that object you will get the same memory location.

Another way to look at this is if you were to set array[2] = 'o' then your matrix would look like this [['.', 'x', 'o'], ['.', 'x', 'o'], ['.', 'x', 'o']]

I think the solution you are looking for though is a deep copy rather than a shallow copy. You can use Python's built-in list.copy() method to achieve this.

for x in range(0, 3):
    matrix.append(array.copy())
VoidTwo
  • 569
  • 1
  • 7
  • 26
  • I didn't downvote, but actually, a shallow copy would work, and indeed, `.append(array.copy())` creates a shallow copy. The *problem* is that `.append(array)` *doesn't create a copy at all*, neither shallow nor deep. – juanpa.arrivillaga Feb 03 '20 at 21:37
  • @juanpa.arrivillaga I believe `.append(array)` does create a shallow copy in the sense that it now has 4 different references: matrix[0], matrix[1], matrix[2], and array. Also, I don't think `.append(array.copy())` creates a shallow copy because it copies all of the elements into a separate reference (which I would consider a deep copy). I'm not sure why I got downvoted, but I guess I should be more clear in the future. – VoidTwo Feb 03 '20 at 21:42
  • You are wrong. `.append(array)` **does not create a copy at all**. That is why all the lists inside the outer list *are the same list*. `array.copy()` creates a shallow copy because it doesn't copy any of the elements inside the list, it simply creates a new list and populates it with the same objects in the list being copied. This is all standard terminology/knowledge for python. Again, I didn't downvote, but I suspect it's because you are not using the correct terminology. See [the docs](https://docs.python.org/3.8/tutorial/datastructures.html#more-on-lists) which say shallow copy explicitly – juanpa.arrivillaga Feb 03 '20 at 21:59
  • @juanpa.arrivillaga I'm not sure why `.copy()` is considered a shallow copy because it doesn't really fit the definition. If you take a look at this older post there are some good explainations for shallow/deep https://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy – VoidTwo Feb 04 '20 at 01:15
  • No, it fits the definition **exactly**. It copies only the structure of the container, not it's elements. Look, I'm not asking for the definitions, I *know* the definitions. I'm explaining to you that you are mistaken. Consider, `a = [[]]; b = a.copy(); b[0].append(1); print(a)` and it will print `[[1]]` since the inner list isn't copied as it would be for a deep copy. And appending to a list will not copy the object being appended, as the this question demonstrates. – juanpa.arrivillaga Feb 04 '20 at 01:41
  • @juanpa.arrivillaga I wanted to believe you, but I had to test this for myself because this was going nowhere. Here is some sample code to test what I was saying (sorry it doesn't really look right in a comment): `matrix = []` `array = ['.', '.', '.']` `for x in range(0, 3):` `matrix.append(array.copy())` `print(matrix)` `matrix[0][1] = 'x'` `print(matrix)` Output: `[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']]` `[['.', 'x', '.'], ['.', '.', '.'], ['.', '.', '.']]` – VoidTwo Feb 04 '20 at 04:28