Заполнить список в Python
Вопрос
У меня есть серия кортежей 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
>>>