Сохранение и обновление списков в словарях Python: почему это происходит?
У меня есть список данных, который выглядит следующим образом:
// 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()): если он есть, добавьте данные, если не создайте пустой список как значение словаря, а затем добавьте данные в следующий цикл.
Ответы
Ответ 1
Посмотрим на
d[t].append(c)
Каково значение d[t]
? Попробуйте.
d = {}
t = 0
d[t]
Что вы получаете? Ой. В d
ничего нет, у которого есть ключ t
.
Теперь попробуйте это.
d[t] = []
d[t]
Ааа. Теперь есть что-то в d
с ключом t
.
Есть несколько вещей, которые вы можете сделать.
- Используйте пример 2.
- Используйте
setdefault
. d.setdefault(t,[]).append(c)
.
- Используйте collections.defaultdict. Вы использовали бы
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 )
Каждое значение словаря должно быть инициализировано некоторой полезной структурой. В этом случае мы проверяем, присутствует ли ключ; когда ключ отсутствует, мы создаем ключ и назначаем пустой список.
SetDefault
Инициализация
d= {}
Использование
d.setdefault(t,list()).append( c )
В этом случае мы используем метод setdefault
для извлечения значения, связанного с ключом, или для создания нового значения, связанного с отсутствующим ключом.
default dict
Инициализация
import collections
d = collections.defaultdict(list)
Использование
d[t].append( c )
defaultdict
использует функцию инициализации для отсутствующих ключей. В этом случае мы предоставляем функцию list
, чтобы создать новый пустой список для отсутствующего ключа.
Ответ 2
Я думаю, вы хотите использовать setdefault. Это немного странно использовать, но делает именно то, что вам нужно.
d.setdefault(t, []).append(c)
Метод .setdefault
вернет элемент (в нашем случае список), который привязан к клавише dict t
, если этот ключ существует. Если этого не произойдет, он свяжет пустой список с ключом t
и вернет его. Таким образом, в любом случае, список будет там, что метод .append
может затем добавить кортеж c
в.
Ответ 3
dict=[] //it not a dict, it a list, the dictionary is dict={}
elem=[1,2,3]
dict.append(elem)
вы можете получить доступ к одному элементу таким образом:
print dict[0] // 0 is the index
вывод будет:
[1, 2, 3]
Ответ 4
В случае, если ваши данные еще не отсортированы по желаемым критериям, вот код, который может помочь сгруппировать данные:
#!/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]]