Search code examples
pythonpython-3.xdictionarysortingdefaultdict

Python DefaultDict Ordering Multiple Values Issue


I am trying to order all of the scores in order of each user's score from highest to lowest. I have attempted this with the code below:

import collections 
from collections import defaultdict
from operator import itemgetter

worker_scores = collections.defaultdict(lambda: collections.deque(maxlen=3))
import operator

worker_scores.clear() 

with open('score_names.txt') as f:
     for line in f: 
        worker,score = line.split(":")
        worker_scores[worker].append(int(score)) 

print("\nThis prints all the highest scores.\n")

for worker in sorted(worker_scores, key=itemgetter(1,2,3), reverse=True):
   print(worker," ".join(map(str,worker_scores[worker])))

   # This should print the maximum value for each key
   print max(worker_scores, key=worker_scores.get)

My text file also appears as follows:

AdamJohnson:10
AdamJohnson:20
AdamJohnson:30
AdamJohnson:40
AdamJohnson:60
AdamJohnson:50 
MichaelJordan:70
MichaelJordan:80
MichaelJordan:100
MichaelJordan:90
DavidSnowman:15
DavidSnowman:20
DavidSnowman:30
DavidSnowman:25

The outcome of the IDLE is as follows:

This prints all the highest scores.

MichaelJordan 80 100 90
AdamJohnson 40 60 50
DavidSnowman 20 30 25

This is what I desired, where the highest scores are at the top and the lowest scores are at the bottom. I discovered the itemgetter technique to do this so I have now accomplished part of my solution.

For the second part, I want the maximum key for each value to be printed. I can use the sorted key to print the keys in alphabetical order, but I cannot print the maximum value for each key. I have used this line from above:

print max(worker_scores, key=worker_scores.get)

To get this result:

AdamJohnson:60
MichaelJordan:100
DavidSnowman:30

But this error arrives: Invalid Syntax (Max). What is going wrong?


Solution

  • You don't need to use max, you can use sorted function and collections.OrderedDict :

    d=OrderedDict()
    
    for k,v in sorted(((i,j.pop()) for i,j in worker_scores.items()),key=operator.itemgetter(1),reverse=True):
        d[k]=v
    
    print d
    OrderedDict([('MichaelJordan', 100), ('DavidSnowman', 30), ('AdamJohnson', 60)])
    

    All that i have done in preceding code is loop over the worker_scores items and pop the last (max) element in deque,(j.pop()) but note that you need to use reverse=True to have the desire order, then add them to OrderedDict.

    And for print the items :

    for k,v in d.items():
        print ':'.join((k,str(v)))
    
    MichaelJordan:100
    DavidSnowman:30
    AdamJohnson:60