I don’t understand why the following code behaves the way it does.
import numpy as np
nbr_arrays = 4
nbr_fields_per_array = 3
nbr_subfields_per_field = 2
# pre-allocate zeros list
zeros = np.zeros(nbr_subfields_per_field)
data = []
for array in range(nbr_arrays):
# pre-allocate the subarray
empty_array = []
for empty_array_index in range(nbr_fields_per_array):
empty_array.append(zeros)
# append pre subarray to data
data.append(empty_array)
# fill up data
for j in range(nbr_fields_per_array):
for k in range(nbr_subfields_per_field):
data[array][j][k] = j*k*array
The generated output data reads now:
[[array([ 0., 6.]), array([ 0., 6.]), array([ 0., 6.])],
[array([ 0., 6.]), array([ 0., 6.]), array([ 0., 6.])],
[array([ 0., 6.]), array([ 0., 6.]), array([ 0., 6.])],
[array([ 0., 6.]), array([ 0., 6.]), array([ 0., 6.])]]
Even zeros reads completely differently:
array([ 0., 6.])
If I look at the identify of the different lists, this is what I get:
id(data[0][0])
Out[72]: 45790208
id(data[1][0])
Out[66]: 45790208
id(data[2][0])
Out[67]: 45790208
id(data[3][0])
Out[68]: 45790208
id(zeros)
Out[69]: 45790208
why are all the references the same? and why does zero suddenly contain non-zero values?
I’d really appreciate it if somebody could explain me what exactly is happening here, and how I have to modify my code to see the expected behaviour (output).
EDIT:
not using zeros but using [[0]*nbr_subfields_per_field for x in range(nbr_fields_per_array)] instead gives me the expected result. but why? why doesn’t the original code work?
Modified code that works:
data = []
for array in range(nbr_arrays):
empty_array = [[0]*nbr_subfields_per_field for x in range(nbr_fields_per_array)]
''' this is causing the weird behaviour
empty_array = []
for empty_array_index in range(nbr_fields_per_array):
empty_array.append(zeros)
'''
data.append(empty_array)
for j in range(nbr_fields_per_array):
for k in range(nbr_subfields_per_field):
data[array][j][k] = j*k*array
This creates a single object.
This keeps appending the same object.
Stop pre-allocating.