Plasmic
Plasmic

Reputation: 105

How to create a matrix of objects of a custom Class in Python?

I am working on an epidemic simulator. However, I have run into a problem: I need to create a matrix of my custom class Location() which has a init() method of __init(self, x_coords, y_coords, population, name)__. All of these parameters are supposed to be random (excluding the name).

The only problem I encounter is when trying to create a matrix / map of these custom locations which I would use in my simulation.
I have tried:

num_rows = 5
num_cols = 5

row = [Location() for i in range(num_rows)]
mat = [list(row) for i in range(num_cols)]

mat[0][0] = Location(...)
num_rows = 5
num_cols = 5

row = [Location() for i in range(num_rows)]
mat = [list(row) for i in range(num_cols)]

mat.append(Location(...))
w, h = 5, 5
Matrix = [[Location() for x in range(w)] for y in range(h)]

Matrix.append(Location(...))
w, h = 5, 5
Matrix = [[Location() for x in range(w)] for y in range(h)]

Matrix[0][0] = Location(...)

All of these encounter the same type error: "Expected type 'List[Location]' (matched generic type '_T'), got 'Location' instead."

I have not been working with Python for very long so I do not know of any workarounds to this and I have found nothing online to help with this.

My full code currently looks like this:

import random


# Location class
class Location:

    def __init__(self, x_coords, y_coords, population, name):
        self._x_coords = x_coords
        self._y_coords = y_coords
        self._population = population
        self._name = name

    # GETTERS VVVV
    def get_x_coords(self):
        return self._x_coords

    def get_y_coords(self):
        return self._y_coords

    def get_population(self):
        return self._population

    def get_name(self):
        return self._name


# Need to initialize a matrix of Location() here

Upvotes: 0

Views: 771

Answers (2)

OpalApps
OpalApps

Reputation: 161

You need to implement __init__(self, x_coords, y_coords, population, name) in your Location class instead of __index__(self, x_coords, y_coords, population, name).

Here is the code (Location constructor parameters simplified):

num_rows = 5
num_cols = 5

class Location:
    def __index__(self, locationIndex=0):
        print( "Location::__index__(" + str( locationIndex) + ")")

    def __init__(self, locationIndex=0):
        print( "Location::__init__(" + str( locationIndex) + ")")

    row = [ Location(i) for i in range( 0, num_rows) ]
    mat = [ list(row) for i in range( 0, num_cols)]

    mat[0][0] = Location(...)
    print( mat)

and the output is:

Location::__init__(0)
Location::__init__(1)
Location::__init__(2)
Location::__init__(3)
Location::__init__(4)
Location::__init__(Ellipsis)

Note, not Location::__index__() but Location::__init__() will be called up on the list comprehension.

The last call Location::__init__(Ellipsis) comes from print( mat).

Upvotes: 1

Kexus
Kexus

Reputation: 659

I believe what you want is something like this

num_col = 5
num_row = 5
mat = [[] for i in range(num_row)] # create a list of empty lists

for row in range(num_row):
    for col in range(num_col):
        mat[row].append(Location(...)) # populate each list with Locations

Upvotes: 1

Related Questions