1

I'm coming from a Java/JS background, and am confused about some behavior I'm seeing when assigning values to a 3D array in Python. (Most posts I've read about this say to use Numpy -- but I want to understand what's going on rather than just "get the job done"!)

What I'm doing

  • I have a 3D array with set sizes for each dimension
  • I have an array of dicts with their locations and a data value
  • I'm looping through the dict array and "filing" the data in the 3D array, based on their location.

The problem

When assigning a value to a single location (x,y,z), Python is instead saving the value to every z-location across the array. What's going on here? Is this a side effect of the way I'm creating the empty array -- e.g., Are the nested "None" arrays treated like "pointers" rather than discrete values? Is it a problem with the assignment statement output[x][y][x]?

Code:

from pprint import pprint
from time import sleep

# Create empty 3d array
output_array = [[[None] * 4] * 4] * 3
pprint(output_array)

# Array of dicts with their location in the 3d array
dicts_to_save = [
    {'loc' : [0,0,0], 'name' : 'A A A'},
    {'loc' : [0,0,1], 'name' : 'A A B'},
    {'loc' : [1,0,0], 'name' : 'B A A'},
    {'loc' : [2,2,2], 'name' : 'C B B'}
]

# Loop through dict array, save name to location
for d in dicts_to_save:
    x = d['loc'][0]
    y = d['loc'][1]
    z = d['loc'][2]

    output_array[x][y][z] = d['name']

    # check assignment
    print()
    pprint(output_array)

    sleep(2)

Output:

[[[None, None, None, None],
  [None, None, None, None],
  [None, None, None, None],
  [None, None, None, None]],
 [[None, None, None, None],
  [None, None, None, None],
  [None, None, None, None],
  [None, None, None, None]],
 [[None, None, None, None],
  [None, None, None, None],
  [None, None, None, None],
  [None, None, None, None]]]

[[['A A A', None, None, None],
  ['A A A', None, None, None],
  ['A A A', None, None, None],
  ['A A A', None, None, None]],
 [['A A A', None, None, None],
  ['A A A', None, None, None],
  ['A A A', None, None, None],
  ['A A A', None, None, None]],
 [['A A A', None, None, None],
  ['A A A', None, None, None],
  ['A A A', None, None, None],
  ['A A A', None, None, None]]]

[[['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None]],
 [['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None]],
 [['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None],
  ['A A A', 'A A B', None, None]]]

[[['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None]],
 [['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None]],
 [['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None],
  ['B A A', 'A A B', None, None]]]

Expected output

The output from the above code SEEMS like it should be:

[[['A A A', None, None, None],
  [None, None, None, None],
  [None, None, None, None],
  [None, None, None, None]],
 [[None, None, None, None],
  [None, None, None, None],
  ...etc, etc

What am I doing wrong??

sepp2k
  • 363,768
  • 54
  • 674
  • 675
Devin
  • 11
  • 3

0 Answers0