Reputation: 391
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
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
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
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
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
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
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