In the article on magic methods for collections we saw how to implement collection behaviours for our example matrix class. We implemented support of built-in function len, support for for loops and the in operator. We also saw how to might implement del, although our 2 by 2 matrix doesn't allow it.

For getting and setting elements, we implemented __getitem__ and __setitem__ as if the matrix was a list of 4 elements. In thi sarticle we will see how to improve that.

Supporting two dimensional selection

Our Matrix is a 2D array, so wouldn't it be nice to support (row, column) style selection? It would be nice if we could use a syntax like:

a[0,1]#row 0, columns 1

Well we can! The numpy library does exactly this, and we can easily support this with our Matrix class.

If you are familiar with dictionaries, you will know that a dictionary is indexed by keys rather than integers. A key can be an integer, or a string, but it can also be a tuple:

d=dict()d[0]=0d['two']=2d[(0,1)]=3print(d)

This gives the result:

{0: 0, 'two': 2, (0, 1): 3}

Thanks to the magic of tuple packing we can write d[(0, 1)] as d[0, 1]. So we can do this:

d[0,1]=10print(d)

which gives:

{0: 0, 'two': 2, (0, 1): 10}

We need to do a similar thing with our matrix class.

Two dimensional getters and setters

Previously our getter and setter accepted and index of the item in list of length 4:

def__getitem__(self,i):returnself.data[i]

But now instead we want to pass in a tuple (row, col). So we need to modify our code like this: