On 1/22/2010 7:17 AM, Gilles Ganault wrote:
Hello

I use a dictionary to keep a list of users connected to a web site.

To avoid users from creating login names that start with digits in
order to be listed at the top, I'd like to sort the list differently
every minute so that it'll start with the next letter, eg. display the
list from A...Zdigits the first time, then B...ZAdigits, etc.


I don't believe anyone has suggested customizing the way that the dictionary's keys are sorted. How about using a string-like object ("RotaKey"), with a changeable sort order:

#--------------------------
import string, time

class RotaKey(object):
    """
    string with rotating sort order
    """
    LETTERS = string.ascii_uppercase

    def __init__(self, instring):
        self.string = instring

    @staticmethod
    def RotateSortOrder():
        """
        rotate the letter sequence for sorting RotaKey objects
        """
        RotaKey.LETTERS = RotaKey.LETTERS[1:] + RotaKey.LETTERS[0]

    def __repr__(self): return "<%s>" % self.string

    def __cmp__(self, other):
        self_first, self_rest = self.string[0], self.string[1:]
        other_first, other_rest = other.string[0], other.string[1:]
        result = cmp(self.LETTERS.index(self_first.upper()),
                     self.LETTERS.index(other_first.upper()))
        if result != 0:
            # first letters differ
            return result
        else:
            # first letters same, compare rest of strings
            return cmp(self_rest, other_rest)

if __name__ == "__main__":
    # create dictionary: keys are RotaKey's, values in range 1001 - ...
    names = map(RotaKey,
            "Ant Zebra Bob Cat2 Ant2 Eagle Bob3 Bob2 Cat Dog".split())
    datadict = dict(zip(names, range(1001, 1001+len(names))))

    # TEST: print, rotate, print, rotate, ...
    for i in range(7):
        if i > 0: RotaKey.RotateSortOrder()
        print "=" * 15, i
        for k in sorted(datadict): print k, datadict[k]
#--------------------------

NOTE: I tried implementing RotaKey as a subclass of "str", but found that the redefinition of __cmp__() was ignored.

You can invoke RotaKey.RotateSortOrder() every minute (or whatever) to change the sort order.

Program output:

=============== 0
<Ant> 1001
<Ant2> 1005
<Bob> 1003
<Bob2> 1008
<Bob3> 1007
<Cat> 1009
<Cat2> 1004
<Dog> 1010
<Eagle> 1006
<Zebra> 1002
=============== 1
<Bob> 1003
<Bob2> 1008
<Bob3> 1007
<Cat> 1009
<Cat2> 1004
<Dog> 1010
<Eagle> 1006
<Zebra> 1002
<Ant> 1001
<Ant2> 1005
=============== 2
<Cat> 1009
<Cat2> 1004
<Dog> 1010
<Eagle> 1006
<Zebra> 1002

 ... etc.

-John
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to