2013-08-15 4 views
2

Поэтому я разрабатывающей программу, которую нужно индексировать вложенный список, используя сохраненный список координат:Более вещий способ индексации со списком координат

например

coordinate = [2,1] 

Для функции, возвращает элемент в вложенного списка, я использую

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

Мои инстинкты программирования говорят мне, что это, кажется, слишком долго, и там должен быть короче способ сделать это, особенно в Python, бушель Я не могу найти ничего подобного. Кто-нибудь знает, есть ли такой метод?

+0

Вы храните координаты внутри комнаты? – Joohwan

+0

Учитывая ваш [предыдущий вопрос] (http://stackoverflow.com/q/17758431/282912), вы уверены, что список является лучшим представлением лабиринта? Словарь даст вам гораздо большую гибкость для представления смежности и тому подобного. Иными словами, как только вы выбрали список списков, вы заперли себя в декартовой плоскости и должны отслеживать многие пары координат. – msw

ответ

1

Вы можете распаковать координаты в более чем одной переменной.

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

или

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

, как вы правильно индекс в вложенный список

с использованием кортежа, вероятно, хороший способ для хранения статического, неизменных координаты

myCoord = (2,1) 

Вашего пути индексации в ваш вложенный room массив выглядит правильно и является удобочитаемым. Мне нужно будет узнать больше о том, как вы его используете, чтобы рекомендовать, какие типы данных использовать.

редактировать
В ответ на ваш комментарий, я бы сказал, что если бы это была функция, принимать x и y как входы или, если это невозможно сделать x,y = myTuple
так, что вы могли бы сделать это :

room[x][y] 

вместо

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

это сделает его бит более читабельный, так как это, кажется, ваша забота. Существует не способ изначально индекса вложенного списка, используя кортеж

+0

Предположительно, индексы не являются постоянными в реальном коде. – delnan

+0

Вот как вы индексируете вложенный список, но для доступа к вложенному списку мне нужно использовать первый и второй элементы координат, используя комнату [координата [0]] [координата [1]], с первым индексом координата [0] и вторая координата [1]. Мой вопрос заключается в том, можно ли использовать переменную с двумя элементами, вы можете ввести вложенный список, не требуя разделения элементов. –

+0

@JacobDenson см. Edit – Stephan

0

Вы можете определить свою собственную функцию рекурсивного индексирования:

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

Что дает:

>>> 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 
+0

Это может быть стандартный трюк в lisp или около того, но рекурсивная функция, которая должна идти на 3 уровня глубины, чтобы искать двумерную координату, не совсем питонична ... –

+0

True. Наверное, я слишком остро реагировал на доступ к LISt, игнорируя часть «pythonic» :) – val

1

Модуль numpy имеет удобное индексирование , Это будет хорошо работать, если ваш room очень большой.

>>> 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 

Чтобы преобразовать room переменную в numpy массив, предполагая, что это 2 мерных вложенный список, просто сделать

>>> 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]]) 
+0

numpy сохраняет день, +1 – Stephan

+0

Почему downvotes? Поскольку переменная называется «комната», скорее всего, OP имеет позиционную сетку в одной комнате. Было бы удобно и проще создавать и получать доступ к этой сетке как 'np.array'. – wflynny

0

Простое решение было бы использовать 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 

Если это не вариант, вы можете создать подкласс список для реализации такого рода индексации:

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

Пример использования:

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

Numpy не входит в стандартную библиотеку, поэтому его необходимо установить отдельно. Хорошо, если вы делаете число-хруст, но используя его для реализации простой игры, это похоже на «убийство москита с помощью канона». –

+0

@BasSwinckels: Я не знаю, работает ли OP над «простой игрой», и мне все равно. Я даю два способа достижения желаемого, и пусть OP (и будущие посетители этого вопроса) выбирают то, что работает для них. Тем не менее, я склоняюсь к тому, что NumPy является излишним для простой игры только потому, что вам нужно установить ее отдельно. Не могли бы вы также утверждать, что PyGame слишком много для простой игры? –

0

Основная проблема заключается в том, что вы используете список в качестве структуры данных для информации, к которой вы хотите получить доступ нестандартным способом.

Сам список прекрасно, вы, возможно, в конечном итоге захотите сделать его объектом, имеющим список как хранилище, но представляющим собой более ориентированный на задачи интерфейс пользователя.

Если вы не готовы к решению класса, это становится вам ближе к Не повторяйте себе:

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

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

Эта функция будет скользить естественно в объект, если вы решили идти по этому пути.

Смежные вопросы