Подтвердить что ты не робот

Сохранение и обновление списков в словарях 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()): если он есть, добавьте данные, если не создайте пустой список как значение словаря, а затем добавьте данные в следующий цикл.

4b9b3361

Ответ 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]]