0

I'm creating a game and I'd like to print out the user scores from highest to lowest.

This is my code so far

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,))

Names in playerscores.txt are stored like:

Bob / 10
Jill / 10

My code takes the last 3 scores from the user(last 3 lives) and uses that as the base. I need print the users names along with the highest scores to the lowest.

The solutions at Sort a Python dictionary by value do not work. I end up getting outputs such as:

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

which are not sorted.

Community
  • 1
  • 1
Sui21245
  • 11
  • 3
  • could you provide the playersscores.txt example – The6thSense Jun 12 '15 at 13:07
  • possible duplicate of [Sort a Python dictionary by value](http://stackoverflow.com/questions/613183/sort-a-python-dictionary-by-value) – Ami Tavory Jun 12 '15 at 13:08
  • @AmiTavory Yes this is a duplicate. Sui21245 go to the link and look at Roberto Bonvallet answer of `from operator import itemgetter sorted(d.items(), key=itemgetter(1))` – Leb Jun 12 '15 at 13:13
  • If you apply the solution you linked to with that dictionary instead: `maxs = { (k, max(v)) for k,v in d.iteritems()}`, is it what you want ? – stellasia Jun 12 '15 at 13:36
  • Top score would be 576. I'm getting AttributeError: 'dict' object has no attribute 'iteritems' for most of these solutions. – Sui21245 Jun 12 '15 at 13:46
  • Please do not vandalize your question. It may be helpful to others. – tobias_k Jun 12 '15 at 14:50

3 Answers3

1

The difference from your case to the answer being pointed as a duplicate is that in thsicase you can compare just with the value of each key, as it is a list. You have to compare (I suppose) with the maximum score in that list - so the keyfunction has to take care of that:

score_list = sorted(player_scores.items(), key=lambda item: max(item[1]))
jsbueno
  • 99,910
  • 10
  • 151
  • 209
  • This still returns a list of playernames and _all_ scores, whereas OP seems to want a list of just the names and top score, so either you have to map the entire dict to just the max values before sorting, or do the same with the result (effectively calling `max` twice for each item). – tobias_k Jun 12 '15 at 14:52
0

First, get the top scores for each player from the list of all scores:

>>> 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()}

Now you can use operator.itemgetter to sort by value. Remember to reverse the result!

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

Finally, to print it, just do something like

for name, score in your_sorted_scores_list:
    print("{:20} - {}".format(name, score))
tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • I don't think using "itemgetter" here simplifies anything. (actually, as we can see, neithr in the simliar answer - its uneeded usage obscured the actual usage of the "key" parameter for people who don't already understand it) – jsbueno Jun 12 '15 at 13:43
  • (And I think it is needles to point out you are iteratign twice over the scores items, and having to deal with an intermediary result when there is no need for it at all) – jsbueno Jun 12 '15 at 13:44
  • @jsbueno I've always had the impression that `itemgetter` is considered more 'pythonic' than using a lambda. Also, I think there's no way around the intermediary result, since OP wants the values to be the top score, so you have to transform the list, either before or after sorting. Either that way, or do `max` again when printing the result. – tobias_k Jun 12 '15 at 13:58
  • Have you seen my answer? – jsbueno Jun 12 '15 at 14:46
0

Python 2 This is one way to do it: 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

Output:

[('Joe', 15), ('Bill', 14), ('Bob', 12), ('Jim', 10), ('Tim', 10), ('Pete', 3), ('Sam', 2)]
Joe T. Boka
  • 6,554
  • 6
  • 29
  • 48