Santi Peñate-Vera
Santi Peñate-Vera

Reputation: 1186

Implement numpy-like slicing in an object

I am writing a sparse matrix library (why is another story...)

So far I have the base class with operator overload for +, -, *, etc...

The minimal code would be something like this:

class SpMat:
    """
    Matrix in compressed-column or triplet form.
    """
    def __init__(self, m=0, n=0):
        """
        @param m: number of rows
        @param n: number of columns
        """

        # number of rows
        self.m = m

        # number of columns
        self.n = n

        self.data = [[0 for x in range(self.n)] for y in range(self.m)]

    def [i, j]:  # this is what I want to implement

        if isinstance(i, int) and isinstance(j, int):
            return self.data[i][j]
        elif isinstance(i, int) and j = :
            return "the row i"  # will implement it
        elif isinstance(j, int) and i = :
            return "the column j"  # will implement it

So in the sample code I want to implement something like def [i, j] to get and set values, but I have no clue how to tell python that when I write myobject[a, b] I want to get the values at the coordinates a, b and when I write myobject[a, b]= some_value I want to set the value at the coordinates a, b.

Upvotes: 0

Views: 35

Answers (1)

Mr Alihoseiny
Mr Alihoseiny

Reputation: 1229

You can override the __getitem__ method of your class.

class SpMat:
    """
    Matrix in compressed-column or triplet form.
    """
    def __init__(self, m=0, n=0):
        """
        @param m: number of rows
        @param n: number of columns
        """

        # number of rows
        self.m = m

        # number of columns
        self.n = n

        self.data = [[0 for x in range(self.n)] for y in range(self.m)]

    def __getitem__(self, key):
        # i and j are integers and you don't need to check the type
        i = key.start  
        j = key.stop
        if isinstance(i, int) and isinstance(j, int):
            return self.data[i][j]
        elif isinstance(i, int) and j = :
            return "the row i"  # will implement it
        elif isinstance(j, int) and i = :
            return "the column j"  # will implement it

The key parameter will be a slice object if you call your instance with syntax like: instance[1:10]. But if you call your instance like: instance[1] the key value will be an integer with a value equal to 1.

In former case, you can get first parameter (in that example: 1) by calling key.start and you can get second parameter (in that example: 10) by calling key.stop.

So maybe it's better for you to check the type of the key parameter at the beggining of the method.

Upvotes: 1

Related Questions