2015-06-12 2 views
0

Я создаю игру, и я бы хотел распечатать пользовательские баллы от наивысшего до самого низкого.Сортировка словаря/списка по значению

Это мой код до сих пор

player_scores = {} 
for line in reversed(open("playerscores.txt").readlines()): 
    name, score = line.rstrip('\n').split('/') 
    score = int(score) 
    if name in player_scores and len(player_scores[name]) < 3: 
     player_scores[name].append(score) 
    if name not in user_scores: 
     player_scores[name] = list((score,)) 

Имена в playerscores.txt сохраняются как:

Bob/10 
Jill/10 

Мой код занимает последние 3 баллов от пользователя (последние 3 жизни) и использует это как основа. Мне нужно печатать имена пользователей вместе с наивысшими баллами до самого низкого уровня.

Решения на Sort a Python dictionary by value не работают. В конечном итоге я получаю такие результаты, как:

[('Alex', [1]), ('Joeseph', [32, 576]), ('Steve', [33]), ('Bob', [55, 22])] 

которые не сортируются.

+0

Вы можете указать пример playersscores.txt – The6thSense

+0

Возможный дубликат слова [Сортировка словаря Python по значению] (http://stackoverflow.com/questions/613183/sort-a-python-dictionary-by-value) –

+0

@AmiTavory Да, это дубликат. Sui21245 перейдите по ссылке и посмотрите на ответ Роберто Бонвалле «от оператора import itemgetter sorted (d.items(), key = itemgetter (1))' – Leb

ответ

1

Отличие от вашего случая к ответу, указываемому как дубликат, заключается в том, что в thsicase вы можете сравнивать только со значением каждой клавиши, так как это список. Вы должны сравнить (я полагаю) с максимальным счетом в этом списке - так keyfunction должен заботиться о том, что:

score_list = sorted(player_scores.items(), key=lambda item: max(item[1])) 
+0

Это все еще возвращает список игровых имен и _all_ баллов, в то время как OP, похоже, хочет получить список только имен и верхнего балла, так что либо вы должны сопоставить весь dict с максимальными значениями перед сортировкой, либо сделать то же самое с result (эффективно называть 'max' дважды для каждого элемента). –

0

Во-первых, получить высшие оценки для каждого игрока из списка всех баллов:

>>> player_scores = dict([('Alex', [1]), ('Joeseph', [32, 576]), ('Steve', [33]), ('Bob', [55, 22])]) 
>>> top_scores = {name: max(scores) for name, scores in player_scores.items()} 

Теперь вы можете использовать operator.itemgetter для сортировки по значению. Не забудьте обратить вспять результат!

>>> sorted(top_scores.items(), key=operator.itemgetter(1), reverse=True) 
[('Joeseph', 576), ('Bob', 55), ('Steve', 33), ('Alex', 1)] 

Наконец, чтобы напечатать, просто сделать что-то вроде

for name, score in your_sorted_scores_list: 
    print("{:20} - {}".format(name, score)) 
+0

Я не думаю, что использование «itemgetter» здесь упрощает что-либо.(на самом деле, как мы видим, neithr в ответе simliar - его неизменное использование заслоняло фактическое использование параметра «ключ» для людей, которые этого еще не поняли) – jsbueno

+0

(И я думаю, что это иголки, чтобы указать, что вы iteratign дважды над пунктами баллов и иметь дело с промежуточным результатом, когда это вообще не нужно) – jsbueno

+0

@jsbueno У меня всегда складывалось впечатление, что 'itemgetter' считается более« pythonic », чем использование лямбда. Кроме того, я думаю, что нет никакого отношения к промежуточному результату, так как OP хочет, чтобы значения были верхним баром, поэтому вам нужно преобразовать список до или после сортировки. Либо так, либо снова 'max' при печати результата. –

0

Python 2 Это один из способов сделать это: EDITED

player_scores = { 
    'Bob': 12, 
    'Pete': 3, 
    'Jim': 10, 
    'Joe': 15, 
    'Bill': 14, 
    'Sam': 2, 
    'Tim': 10 
} 

k = sorted(player_scores, key=player_scores.__getitem__, reverse=True) 
v = sorted(player_scores.values(), reverse=True) 
sorted_player_scores = zip(k,v) 
print sorted_player_scores 

Выход:

[('Joe', 15), ('Bill', 14), ('Bob', 12), ('Jim', 10), ('Tim', 10), ('Pete', 3), ('Sam', 2)] 
+0

Это имеет квадратичную сложность! Кроме того, это не сработает, если у двух игроков одинаковый балл. –

+0

@tobias_k спасибо за комментарий, я отредактировал свой ответ соответственно. Я ценю это! –