Ian Campbell Ian Campbell - 2 months ago 17
Python Question

Automated Inclusion of Objects in Python List

I'm declaring a class, and in the

__init__
method, I'm declaring two variables which will be associated with an instance of that class. Each declared variable is initialised as a NumPy array of zeros that is later filled with other data.

At some point, outside of this
__init__
method, I need to loop through an object containing each of these variables (NumPy arrays) and reset the array values in each to zero. Thus, in the
__init__
method, I would like to add all of these variables to a list to later iterate through. If I do that once manually, it's trivial.

However, I need to frequently add and remove some number of these variables being declared in
__init__
. Every time I do that, I don't want to have to manually adjust the variables that are contained in the list.

How can I create a
list
,
dict
, or other container of these variables that automatically adjusts itself so it contains all of these variables being initialised, regardless of the number of those variables? As an additional complication,
self.container_of_arrays
must not contain "other" variables from
__init__
, such as
self.array_length
.

What I have, where
self.container_of_arrays
must currently be manually adjusted if a
self.my_variable_three
is created:

class generic_class():
def __init__(self, array_width_one, array_width_two):
self.array_length = some_integer

self.my_variable_one = numpy.zeros((self.array_length, array_width_one), dtype=float)
self.my_variable_two = numpy.zeros((self.array_length, array_width_two), dtype=float)

self.container_of_arrays = [self.my_variable_one, self.my_variable_two]


I tried to declare my variables within a
dict
, so that from the very start they are contained within that
dict
, but this leads to there being references to undefined variables. E.g.

self.container_of_arrays = OrderedDict([(self.my_variable_one, numpy.zeros((self.array_length, array_width_one), dtype=float)),
(self.my_variable_two, numpy.zeros((self.array_length, array_width_two), dtype=float))
])


Update:

xli's answer provides the correct solution. As suggested, it's possible to access the arrays by name using a dict or OrderedDict. For anyone who wants to do so, here's the code I've actually implemented:

my_data = [('variable_one_name', len(variable_one_data)),
('variable_two_name', len(variable_two_data)),
] # Intentionally outside the class in a location where variables are added by the user

class generic_class():
def __init__(self, array_length, my_data):

self.container_of_arrays = OrderedDict((variable_name, numerix.zeros((array_length, array_width), dtype=float))
for variable_name, array_width in my_data)

xli xli
Answer

Instead of creating a variable for each numpy array, why don't you just create a list of arrays containing each array you need, and reference them by index?

class generic_class():
    def __init__(self, array_length, array_widths=[]):
        self.array_length = array_length
        self.arrays = [
             numpy.zeros((self.array_length, array_width), dtype=float) 
             for array_width in array_widths
        ]

Then you can access each array by index as self.arrays[i].

Or, if you need to access the array by name, you can use a dict with just a string (the name of the array) as the key for each array.

Comments