HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Custom array indexing

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arraycustomindexing

Problem

Note that this code is not going to be used for anything, it's more of a thought experiment. I've been seeing a lot of NumPy code lately and noticed that they use a custom indexing process, presumably by defining an object's __getitem__ method. I wrote the following class that allows for a multi-dimensional array to be indexed as ls[1,2] instead of ls[1][2].

Is there a better way to write this method? It seems unnecessary to be keeping track of current as the item look-up is descended, but I can't think of a way to avoid it.

class Array(list):
    def __getitem__(self, indices):
        current = super(self.__class__, self)
        for index in indices:
            current = current.__getitem__(index)
        return current

a = Array([[[1,2,3],[4,5,6]],
           [[0,1,2],[9,8,7]]])
print a[1,0,2] # 2

Solution

Let me start by saying that there's nothing wrong with your approach, and almost nothing wrong with your implementation. Just two things I would like to remark.

Use of super.

Because of your use of super, you actively prevent subclassing. In Python 2.7, you're supposed to spell the name out long:

current = super(Array, self)


Consider this:

class Brray(Array): pass
b = Brray([[[1,2,3],[4,5,6]],
           [[0,1,2],[9,8,7]]])
print b[1, 0, 2]


This gives us

TypeError: 'int' object is not iterable


By using super(Array, self) instead, everything is fine again.

Subclassing list

You're subclassing list, which causes a = Array(...) to make a shallow copy of the supplied iterable. I myself would prefer composition:

class Array(object):
    def __init__(self, wrapped):
        self._wrapped = wrapped
    def __getitem__(self, indices):
        current = self._wrapped
        for index in indices:
            current = current[index]
        return current


(This is also aided by the fact that I don't like calling 'dunder' (double under) methods directly.

Code Snippets

current = super(Array, self)
class Brray(Array): pass
b = Brray([[[1,2,3],[4,5,6]],
           [[0,1,2],[9,8,7]]])
print b[1, 0, 2]
TypeError: 'int' object is not iterable
class Array(object):
    def __init__(self, wrapped):
        self._wrapped = wrapped
    def __getitem__(self, indices):
        current = self._wrapped
        for index in indices:
            current = current[index]
        return current

Context

StackExchange Code Review Q#119432, answer score: 4

Revisions (0)

No revisions yet.