2015-02-08 4 views
1


Я недавно создавал игру для угадывания своих коллег как проект для изучения Python 3.3x. Я хранение результатов в виде текстового файла, отформатированный с именем и оценка, разделенных двоеточием, как показано на рисунке ...Создание каждого хранилища ключей не более 5 значений в словаре Python

Adam:12 
Dave:25 
Jack:13 
Adam:34 
Dave:23 

Текстовый файл читается с помощью следующего кода, благодаря Padraic Каннингем.

from collections import defaultdict 
d = defaultdict(list) 
with open('guesses.txt') as f: 
    for line in f: 
     name,val = line.split(":") 
     d[name].append(int(val)) 

for k in sorted(d): 
    print(k," ".join(map(str,d[k]))) 

Проблема в том, что я хочу увидеть последние четыре оценки Дейва, Адама и Джека. Один из способов, который я думал об этом, - это как-то прочитать список выше и отменить его, чтобы он сначала увидел самые последние результаты. Я думал, что я мог бы первый обратный словарь, используя строку коды ниже:

inv_map = {v: k for k, v in d.items()} 

Но это не работает, так как она возвращает ошибку:

TypeError: unhashable type: 'list' 

Как я хочу, чтобы хранить 4 наиболее последние результаты, тогда мне нужно будет убедиться, что самый старый результат удаляется каждый раз, когда приходит новый результат, и обновляет словарь.

Как я могу убедиться, что для каждой клавиши назначено только 4 максимальных значения? Может ли это быть сделано путем обращения к словарю? Я попытался выяснить, следуют ли другие вопросы по тому же принципу, но я не нашел ничего такого.

ПРИМЕЧАНИЕ Я видел метод itemgetter, но у меня более одного значения для каждой клавиши.

Текстовый файл будет выглядеть следующим образом:

Adam:12 
Dave:25 
Jack:13 
Adam:34 
Dave:23 
Jack:17 
Adam:28 
Adam:23 
Dave:23 
Jack:11 
Adam:39 
Dave:44 
Jack:78 
Dave:38 
Jack:4  
+1

возможно дубликат [Пользователь балл сохранения программы] (http://stackoverflow.com/questions/28326725/a-user-score-saving-program) –

+1

Как вы можете видеть, в двух экземплярах, вы можете сериализуйте файлы в реальные объекты python (в вашем случае это будет словарь из списка string->), что должно сделать это ** намного проще. –

ответ

2

Вы можете использовать defaultdict с deque(maxlen=4), чтобы справиться с этим.

import collections 

d = collections.defaultdict(lambda: collections.deque(maxlen=4)) 
# defaultdict accepts as an argument a function that returns the default 
# state of the value of undefined keys. In this case we make an anonymous 
# function that returns a `collections.deque` with maxlen of 4. 

# we could also do 
# # import functools, collections 
# # d = collections.defaultdict(functools.partial(collections.deque, 
# #            maxlen=4)) 

with open('path/to/file.txt', 'r') as infile: 
    for line in infile: 
     player,score = line.strip().split(":") 
     d[player].append(int(score)) 

Однако вам, вероятно, лучше просто создать эту структуру данных для начала и травления объекта.

import pickle 

# `highscores` is some previously populated high score dict 

def save_scores(filename): 
    with open(filename, 'w') as outfile: 
     pickle.dump(highscores, outfile) 

def load_scores(filename): 
    with open(filename, 'r') as infile: 
     highscores = pickle.load(infile) 
    return highscores 
+0

О, хорошо. Но, когда я использую свой метод 'print (dict (d))', он выводит это: –

+0

'{'Jack': deque ([17, 11, 78, 4], maxlen = 4), 'Dave': deque ([23, 23, 44, 38], maxlen = 4), 'Adam': deque ([34, 28, 23, 39], maxlen = 4)} ' –

+0

Как мне избавиться от deque и maxlen, чтобы открыть сам словарь? или даже лучше, как я мог затем напечатать его аккуратно, так что он только читает «Джек 17 11 78 4» без скобок? @adamsmith –