Search code examples
pythondeap

Python object as a list of lists of dictionaries


I'm trying to develop a class that behaves as a list of lists. I need it to pass it as a type for an individual, in deap framework. Presently, I'm working with numpy object array. Here is the code.

import numpy

class MyArray(numpy.ndarray):
    def __init__(self, dim):
        numpy.ndarray.__init__(dim, dtype=object)

But when I try to pass values to the object of MyArray,

a = MyArray((2, 2))
a[0][0] = {'procID': 5}

I get an error,

Traceback (most recent call last):
File "D:/PythonProjects/NSGA/src/test.py", line 23, in <module>
    'procID': 5
TypeError: float() argument must be a string or a number, not 'dict'

Any suggestions are welcome. You can also show me a different way without making use of numpy which facilitates type creation.

A similar question can be found here


Solution

  • According to the documentation, it looks like ndarray uses __new__() to do its initialization, not __init__(). In particular, the dtype of the array is already set before your __init__() method runs, which makes sense because ndarray needs to know what its dtype is to know how much memory to allocate. (Memory allocation is associated with __new__(), not __init__().) So you'll need to override __new__() to provide the dtype parameter to ndarray.

    class MyArray(numpy.ndarray):
        def __new__(cls, dim):
            return numpy.ndarray.__new__(cls, dim, dtype=object)
    

    Of course, you can also have an __init__() method in your class. It will run after __new__() has finished, and that would be the appropriate place to set additional attributes or anything else you may want to do that doesn't have to modify the behavior of the ndarray constructor.

    Incidentally, if the only reason you're subclassing ndarray is so that you can pass dtype=object to the constructor, I'd just use a factory function instead. But I'm assuming there's more to it in your real code.