[Tutor] Sorting dictionary values

dman dsh8290@rit.edu
Wed, 15 Aug 2001 14:03:06 -0400


On Wed, Aug 15, 2001 at 01:53:31PM -0400, W. Jarrett Campbell wrote:
| > 
| > I'm no longer subscribed to this list, but you guys were so helpful
| > when I was learning Python a few months ago I thought I'd throw this
| > one at you.  Please respond to my email address directly in addition
| > to any posts to the list since I'm no longer an active
| > subscriber...thanks!
| > 
| > 
| > Problem:
| > ------
| > I'm building a "Leader Board" application which tracks user names
| > and displays the top 10 scores from a contest
| 
| > I'm using shelve/pickle for my persistence so basically what I'm
| > confronted with is something that looks like this:
| > 
| > userDB = {uniqueUserID:userData}
| > 
| > where userData is itself a dictionary like
| > 
| > userData = {"fname": "Jarrett",
| >                          "lname": "Campbell",
| >                          "email": "jarrett@ydyn.com",
| >                          "score":"98.8"}
| > 
| > 
| > What I need to do is find the 10 uniqueUserIDs from userDB where the
| > value of "score" is the in the top 10 of all the records and sort
| > them in order from highest to lowest
| 
| > Once that is done, I have a routine to display the leaderboard.
| > 
| > Any suggestions for an efficient way to do this?

Dictionaries can't be sorted because the keys are hashed instead.  I
think you need to iterate over your db and create a list of all the
users, then sort them based on score.  The easiest way would probably
be to make a class for the userData instead of using a plain
dictionary -- that way you can define the comparision to behave the
way you want it (based on score).

ex :

class User :
    def __init__( self , fname , lname , email , score=0 ) :
        self.fname = fname
        self.lname = lname
        self.email = email
        self.score = score

    def __lt__( self , other ) :
        return self.score < other.score

    def __gt__( self , other ) :
        return self.score > other.score

    <...>


#
# 1)    use an number, not a string for the score -- you want to do
#       numerical comparisions )
#
# 2)    build the list however you would normally do it
#
user_list = [
    User( "Jarrett" , "Campbell" , "jarrett@ydyn.com" , 98.8 ) ,
    User( "John" , "Doe" , "void@null.com" , 50 ) ,
    ]

user_list.sort()
print "The top ten are :"
print user_list[:10]

HTH,
-D