"""A set of comparer classes.""" class CmpComposite: """Takes a list of compare functions and sorts in that order.""" def __init__(self,*comparers): self.comparers=comparers def __call__(self,a,b): for cmp in self.comparers: c=cmp(a,b) if c: return c return 0 class CmpInverse: """Inverses the effect of a cmp.""" def __init__(self,cmp): self.cmp=cmp def __call__(self,a,b): return -self.cmp(a,b) class CmpColumn: """Sorts on an index of a sequence.""" def __init__(self,column): self.column=column def __call__(self,a,b): return cmp(a[self.column],b[self.column]) class CmpAttr: """Sorts on an attribute.""" def __init__(self, attr): self.attr = attr def __call__(self, x, y): return cmp(getattr(x, self.attr), getattr(y, self.attr)) def test(): l=[3,5,6,71,2,3,4,5] print 'sort inv' s=CmpInverse(cmp) l.sort(s) print ' ',l table=[ (1,2), (1,3), (1,0), (2,0), (0,3), (3,2) ] print 'sort l[0], inv l[1]' table.sort(CmpComposite(CmpColumn(0),CmpInverse(CmpColumn(1)))) print ' ',table print 'sort inv l[1], l[0]' table.sort(CmpComposite(CmpInverse(CmpColumn(1)),CmpColumn(0))) print ' ',table class Spam: def __init__(self, spam, eggs): self.spam = spam self.eggs = eggs def __repr__(self): return 'Spam(s=%s,e=%s)' %(repr(self.spam),repr(self.eggs)) a = [Spam(1, 4), Spam(9, 3), Spam(4,6),Spam(4,4)] print "sort spam:" a.sort(CmpAttr('spam')) print ' ',a print "sort inv spam:" a.sort(CmpInverse(CmpAttr('spam'))) print ' ', a print "sort spam, eggs:" a.sort(CmpComposite(CmpAttr('spam'),CmpAttr('eggs'))) print ' ',a print "sort eggs, spam:" a.sort(CmpComposite(CmpAttr('eggs'),CmpAttr('spam'))) print ' ',a print "sort eggs, inv spam:" a.sort(CmpComposite(CmpAttr('eggs'),CmpInverse(CmpAttr('spam')))) print ' ',a if __name__=='__main__': test()