Jacob Denson
Jacob Denson

Reputation: 391

More pythonic method of indexing with a list of coordinates

So I am designing a program which needs to index a nested list, using a stored list of coordinates:

e.g

coordinate = [2,1]

For a function which returns the element in the nested list, I use

return room[coordinate[0]][coordinate[1]]

My programming instincts tell me that this seems overly long, and there should be a shorter method of doing this especially in Python, but I can't seem to find anything of the sort. Does anyone know if there is a method like this?

Upvotes: 2

Views: 14377

Answers (6)

Stephan
Stephan

Reputation: 17971

coordinates[2][1] = "blah"

is how you properly index into a nested list

using a tuple is probably a good way to store a static, immutable coordinate

myCoord = (2,1)

Your way of indexing into your nested room array looks right and is a readable option. I'd have to see more of how you are using it to make a recommendation on what data types to use.

edit
In response to your comment, I'd say if this was a function, to accept x, and y as inputs or if that is not possible do x,y = myTuple
so that you could then do this:

room[x][y]

instead of

room[coords[0]][coords[1]]

That will make it a bit more readable since that seems to be your concern. There is NOT a way to natively index a nested list using a tuple

Upvotes: 1

msw
msw

Reputation: 43487

The underlying problem is that you are using a list as the data structure for information that you want to access in a non-listy way.

The list itself is fine, you might ultimately want to make it an object that has-a list as its storage but presents a more task-oriented interface the the user.

If you aren't ready to tackle a class, this gets you closer to Don't Repeat Yourself:

def room_at_coordinate(rooms, coordinate)
    return rooms[coordinate[0]][coordinate[1]]

>>> room_at_coordinate(rooms, coordinate)
'bathroom'

This function will slip naturally into an object should you decide to go that route.

Upvotes: 0

Sven Marnach
Sven Marnach

Reputation: 601529

An easy solution would be to use NumPy:

In [1]: import numpy

In [2]: a = numpy.arange(15).reshape(3, 5)

In [3]: a
Out[3]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

In [4]: coords = (2, 1)

In [5]: a[coords]
Out[5]: 11

If this is not an option, you could subclass list to implement this kind of indexing:

class MyList(list):
    def __getitem__(self, index):
        if isinstance(index, collections.Iterable):
            return reduce(operator.getitem, index, self)
        return list.__getitem__(self, index)

Example usage:

>>> a = MyList([[ 0,  1,  2,  3,  4],
                [ 5,  6,  7,  8,  9],
                [10, 11, 12, 13, 14]])
>>> coords = (2, 1)
>>> a[coords]
11

Upvotes: 0

Radio-
Radio-

Reputation: 3171

You can unpack the coordinates into more than one variable.

i, j = [2, 1]
return room[i][j]

or

coordinates = [2, 1]
### do stuff with coordinates
i, j = coordinates
return room[i][j]

Upvotes: 1

wflynny
wflynny

Reputation: 18521

The numpy module has convenient indexing. It would work well if your room is very large.

>>> import numpy as np
>>> room = np.arange(12).reshape(3,4)
>>> room
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> coords = (2, 1) # it's important this is a tuple
>>> room[coords]
9

To convert your room variable to a numpy array, assuming it is a 2 dimensional nested list, just do

>>> room = [[0, 1, 2, 3, 4],
            [0, 1, 2, 3, 4],
            [0, 1, 2, 3, 4],
            [0, 1, 2, 3, 4],
            [0, 1, 2, 3, 4]]
>>> room = np.array(room)
array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])

Upvotes: 1

val
val

Reputation: 8689

You could define your own recursive indexing function:

def rec(x, i):
    if i: return rec(x[i[0]], i[1:])
    else: return x

Which gives:

>>> room = [[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],[[13,14,15],[16,17,18]]]
>>> rec(room, (2,1))
[16, 17, 18]
>>> rec(room, [2,1,1])
17

Upvotes: 0

Related Questions