This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: 3D Array Assignment to all 2D sub-arrays
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.7, Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: John Bachman, eric.snow
Priority: normal Keywords:

Created on 2019-03-27 15:05 by John Bachman, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (2)
msg338963 - (view) Author: John Bachman (John Bachman) Date: 2019-03-27 15:05
Tested on Python3.6 on Ubuntu 18.04
The following code snippet produces the wrong results.

Snippet:

M = [[[0] * 2] * 2] * 2                                                                
M[0][0][0] = 1                                                                                                                                                                 
print(M[0][0][0]) # Should be one                                                                      
print(M[1][0][0]) # Should still be zero 

My output:
1
1

For some reason when you assign to any list inside the 3D matrix, all lists in the array are changed, 2D Matrix works but 3D modifies every 2D matrix.
msg338969 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2019-03-27 15:39
In Python, multiplication on a list does not make copies of the values in the original list.  So what you have done is equivalent to the following:

  a = [0, 0]
  b = [a, a]
  M = [b, b]

Hence:

  >>> M[0] is M[1]
  True
  >>> M[0][0] is M[0][1]
  True
  >>> M[1][0] is M[1][1]
  True
  >>> M[0][0] is M[1][0]
  True

So the following *all* modify the first value in "a":

  M[0][0][0] = 1
  M[1][0][0] = 1
  M[0][1][0] = 1
  M[1][1][0] = 1

That is why you are seeing the result you reported.  Depending on your needs, better solutions include using a list comprehension, spelling out the for loops (for readability), a helper function (for complex problems), or simply spelling out the full list literal instead of composing it.  Regardless, I highly recommend using a solution that is easy for a new reader to understand.  Even if no one else will read this code, your six-months-from-now self will thank you. :)
History
Date User Action Args
2022-04-11 14:59:13adminsetgithub: 80631
2019-03-27 15:39:37eric.snowsetstatus: open -> closed

nosy: + eric.snow
messages: + msg338969

resolution: not a bug
stage: resolved
2019-03-27 15:09:46John Bachmansetversions: + Python 3.7
2019-03-27 15:05:38John Bachmancreate