Вопрос

У меня есть серия кортежей Python, представляющих координаты:

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]

Я хочу создать следующий список:

l = []
for t in tuples:
  l[ t[0] ][ t[1] ] = something

Я получаю IndexError:Индекс списка вне диапазона.

Я знаю PHP, и я ожидал, что в Python вы сможете создавать списки, начинающиеся с индекса > 0, т.е.делайте пробелы, а затем заполняйте их, но, похоже, вы не можете.

Идея состоит в том, чтобы потом отсортировать списки.Я знаю, что могу сделать это со словарем, но, насколько мне известно, словари нельзя сортировать по ключам.Обновлять:Теперь я знаю, что они могут — см. принятое решение.

Редактировать:Я хочу создать двумерный массив, который будет представлять матрицу, описанную координатами кортежа, а затем выполнить итерацию по порядку.Если я использую словарь, у меня нет гарантии, что перебор ключей будет в порядке -> (0,0) (0,1) (0,2) (1,0) (1,1) (1,2) ) (2,0) (2,1) (2,2)

Кто-нибудь может помочь?

Это было полезно?

Решение

Что именно вы подразумеваете под «но, насколько я знаю, словари нельзя сортировать по ключам»?

Хотя это не совсем то же самое, что «отсортированный словарь», вы может легко превратить словарь в список, отсортированный по ключу, который, похоже, вам нужен:

>>> tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
>>> l = {}
>>> for t in tuples:
...    l[t] = "something"
>>> sorted(l) # equivalent to sorted(l.keys())
[(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)]
>>> sorted(l.items()) # make a list of (key, value) tuples, and sort by key
[((0, 0), 'something'), ((0, 1), 'something'), ((1, 0), 'something'), ((1, 1), 'something'), ((2, 1), 'something')]    

(Я повернулся something в строку «что-то», чтобы код работал)

Однако, чтобы использовать это в вашем случае (если я правильно понимаю), вам все равно нужно будет заполнить словарь значениями None или чем-то еще для каждого «пустого» координатного кортежа)

Другие советы

Нет, вы не можете создать список с пробелами.Но вы можете создать словарь с ключами кортежа:

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
l = {}
for t in tuples:
    l[t] = something

Обновлять:Попробуйте использовать NumPy, он обеспечивает широкий спектр операций над матрицами и массивами.Цитируйте из бесплатного PDF-файла на NumPy, доступного на сайте (3.4.3 Индексация Flat Iterator): «Как упоминалось ранее, X.flat возвращает итератор, который будет перебирать весь массив (в стиле C-непрерывного, причем последний индекс меняется быстрее всего».Похоже на то, что вам нужно.

Вам следует посмотреть дикты на предмет чего-то подобного.

for t in tuples:
  if not l.has_key(t[0]):
    l[t[0]] = {}
  l[t[0]][t[1]] = something

Однако перебор dict немного отличается от перебора по списку.В этом вам помогут функцииkeys(),values() и items().

РЕДАКТИРОВАТЬ:попробуйте что-то вроде этого для заказа:

for x in sorted(l.keys()):
   for y in sorted(l[x].keys()):
       print l[x][y]

Вы создаете одномерный список l и хотите использовать его как двумерный список.Вот почему вы получаете ошибку индекса.

У вас есть следующие возможности:создайте карту и используйте кортеж t в качестве индекса:

l = {}
l[t] = something

и вы получите записи в l как:

{(1, 1): something}

если вам нужна традиционная структура массива, я советую вам посмотреть бестолковый.С numpy вы получаете n-мерные массивы с «традиционной» индексацией.

Как я уже упоминал, используйте numpy,

с помощью numpy вы можете создать двумерный массив, заполненный нулями, единицами или...Вы можете заполнить любое желаемое значение индексацией [x,y] по своему желанию.Конечно, вы можете перебирать строки и столбцы или весь массив в виде списка.

Если вы заранее знаете размер, вы можете составить такой список списков.

>>> x = 3
>>> y = 3
>>> l = [[None] * x for i in range(y)]
>>> l
[[None, None, None], [None, None, None], [None, None, None]]

Что вы затем можете повторить, как вы изначально предлагали.

Расширение Натанответ,

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
x = max(tuples, key = lambda z : z[0])[0] + 1
y = max(tuples, key = lambda z : z[1])[1] + 1
l = [[None] * y for i in range(x)]

И тогда ты сможешь делать все, что захочешь

Как упоминалось ранее, вы не можете составлять списки с пробелами, и словари могут быть здесь лучшим выбором.Хитрость заключается в том, чтобы убедиться, что l[t[0]] существует, когда вы ставите что-то на место t[1].Для этого я бы использовал defaultdict.

import collections
tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
l = collections.defaultdict(dict)
for t in tuples:
    l[t[0]][t[1]] = something

С l является значением по умолчанию, если l[t[0]] не существует, он создаст пустой словарь, в который вы сможете поместить свой something в позиции t[1].

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

Приведенные решения dict, вероятно, лучше всего подходят для большинства целей.Что касается вашей проблемы с перебором ключей по порядку, обычно вы вместо этого перебираете координатное пространство, а не клавиши dict, точно так же, как и для вашего списка списков.Используйте .get, и вы можете указать значение по умолчанию, которое будет использоваться для пустых ячеек, или альтернативно использовать "collections.defaultdict", чтобы определить значение по умолчанию во время создания dict.например.

for y in range(10):
    for x in range(10):
        value = mydict.get((x,y), some_default_value)
        # or just "value = mydict[x,y]" if used defaultdict

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

max_x, max_y = map(max, zip(*tuples))
l=[[something if (x,y) in tuples else 0 for y in range(max_y+1)] 
     for x in xrange(max_x+1)]

Если список кортежей, скорее всего, будет длинным, из соображений производительности вы можете использовать набор для поиска, например:(x,y) in tuples" выполняет сканирование списка, а не быстрый поиск по хешу.т. е. измените вторую строку на:

tuple_set = set(tuples)
l=[[something if (x,y) in tuple_set else 0 for y in range(max_y+1)] 
     for x in xrange(max_x+1)]

Я думаю, вы объявили только одномерный список.

Я думаю, вы заявляете это как

l = [][]

Редактировать:Это синтаксическая ошибка

>>> l = [][]
  File "<stdin>", line 1
    l = [][]
           ^
SyntaxError: invalid syntax
>>> 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top