У меня есть список данных, который выглядит следующим образом:
// timestep,x_position,y_position
0,4,7
0,2,7
0,9,5
0,6,7
1,2,5
1,4,7
1,9,0
1,6,8
... и я хочу, чтобы это выглядело так:
0, (4,7), (2,7), (9,5), (6,7)
1, (2,5), (4,7), (9,0), (6.8)
Мой план состоял в том, чтобы использовать словарь, где значение t является ключом для словаря, а значение для ключа будет списком. Затем я мог бы добавить каждый (x, y) в список. Что-то типа:
# where t = 0, c = (4,7), d = {}
# code 1
d[t].append(c)
Теперь это приводит к сбою IDLE. Однако, если я это сделаю:
# code 2
d[t] = []
d[t].append(c)
... это работает.
Возникает вопрос: почему код 2 работает, а код 1 - нет?
PS Любые улучшения в том, что я планирую сделать, будут очень интересны !! Я думаю, мне придется проверять словарь в каждом цикле через ввод, чтобы увидеть, существует ли уже ключ словаря, я думаю, используя что-то вроде max (d.keys ()): если он есть, добавить данные, если не создать пустой список в качестве значения словаря, а затем добавить данные в следующем цикле.






Давайте посмотрим на
d[t].append(c)
В чем ценность d[t]? Попробуй это.
d = {}
t = 0
d[t]
Что вы получаете? Ой. В d нет ничего, что имеет ключ t.
А теперь попробуйте это.
d[t] = []
d[t]
Ах. Сейчас есть что-то в d с ключом от t.
Вы можете сделать несколько вещей.
setdefault. d.setdefault(t,[]).append(c).defaultdict(list) вместо простого словаря {}.Изменить 1. Оптимизация
Учитывая входные строки из файла в приведенной выше форме: ts, x, y, процесс группировки не требуется. Нет причин переходить от простого списка (ts, x, y) к более сложному список (ts, (x, y), (x, y), (x, y), ...). Исходный список можно обработать точно так, как он был получен.
d= collections.defaultdict(list)
for ts, x, y in someFileOrListOrQueryOrWhatever:
d[ts].append( (x,y) )
Изменить 2. Ответить на вопрос
"при инициализации словаря вам нужно сообщить словарю, как будет выглядеть структура данных ключ-значение?"
Я не уверен, что означает вопрос. Поскольку все словари являются структуры ключ-значение, вопрос не очень ясен. Итак, я рассмотрю три альтернативы, которые могут ответить на вопрос.
Пример 2.
Инициализация
d= {}
Использовать
if t not in d:
d[t] = list()
d[t].append( c )
Каждое значение словаря должно быть инициализировано некоторой полезной структурой. В этом случае мы проверяем наличие ключа; когда ключ отсутствует, мы создаем ключ и назначаем пустой список.
Установить по умолчанию
Инициализация
d= {}
Использовать
d.setdefault(t,list()).append( c )
В этом случае мы используем метод setdefault, чтобы либо получить значение, связанное с ключом, либо создать новое значение, связанное с отсутствующим ключом.
dict по умолчанию
Инициализация
import collections
d = collections.defaultdict(list)
Использовать
d[t].append( c )
defaultdict использует функцию инициализации недостающих клавиш. В этом случае мы предоставляем функцию list, чтобы создать новый пустой список для отсутствующего ключа.
Значит ли это, что при инициализации словаря вам нужно сообщить словарю, как будет выглядеть структура данных «ключ-значение»? Извините, я исхожу из фона Perl, который я не использовал в гневе годами, так что, возможно, я продолжаю работать с разбитыми воспоминаниями, поскольку был уверен, что вы можете сделать это анонимно.
dict=[] //it's not a dict, it's a list, the dictionary is dict = {}
elem=[1,2,3]
dict.append(elem)
вы можете получить доступ к отдельному элементу таким образом:
print dict[0] // 0 is the index
вывод будет:
[1, 2, 3]
Python достаточно сбивает с толку своей нерегулярной скобкой, чтобы добавить к ней имя функции (dict () должна возвращать пустой dict), похожее на структуру данных, и сделать ее переменной.
Я думаю, вы хотите использовать setdefault. Это немного странно в использовании, но делает именно то, что вам нужно.
d.setdefault(t, []).append(c)
Метод .setdefault вернет элемент (в нашем случае список), связанный с ключом dict t, если этот ключ существует. В противном случае он привяжет пустой список к ключу t и вернет его. Так или иначе, будет список, в который метод .append может затем добавить кортеж c.
Если ваши данные еще не отсортированы по желаемым критериям, вот код, который может помочь сгруппировать данные:
#!/usr/bin/env python
"""
$ cat data_shuffled.txt
0,2,7
1,4,7
0,4,7
1,9,0
1,2,5
0,6,7
1,6,8
0,9,5
"""
from itertools import groupby
from operator import itemgetter
# load the data and make sure it is sorted by the first column
sortby_key = itemgetter(0)
data = sorted((map(int, line.split(',')) for line in open('data_shuffled.txt')),
key=sortby_key)
# group by the first column
grouped_data = []
for key, group in groupby(data, key=sortby_key):
assert key == len(grouped_data) # assume the first column is 0,1, ...
grouped_data.append([trio[1:] for trio in group])
# print the data
for i, pairs in enumerate(grouped_data):
print i, pairs
Выход:
0 [[2, 7], [4, 7], [6, 7], [9, 5]]
1 [[4, 7], [9, 0], [2, 5], [6, 8]]
"Не работает холостой ход?" Не очень содержательно. Укажите фактическое сообщение об ошибке.