Raymond Hettinger wrote: > dwelden wrote: >> I have successfully used the sort lambda construct described in >> http://mail.python.org/pipermail/python-list/2006-April/377443.html. >> However, how do I take it one step further such that some values can be >> sorted ascending and others descending? Easy enough if the sort values >> are numeric (just negate the value), but what about text? >> >> Is the only option to define an external sorting function to loop >> through the list and perform the comparisons one value at a time? > > The simplest way is to take advantage of sort-stability and do > successive sorts. For example, to sort by a primary key ascending and > a secondary key decending: > > L.sort(key=lambda r: r.secondary, reverse=True) > L.sort(key=lambda r: r.primary) > > A less general technique is to transform fields in a way that reverses > their comparison order: > > L.sort(key=lambda r: (-r.age, r.height)) # sorts descending age > and ascending height
You can get generality if you are willing to pay the performance penalty: >>> items [(3, 1), (2, 2), (1, 1), (1, 3), (2, 1), (2, 3), (1, 2)] >>> class Reverse: ... def __cmp__(self, other): ... return -cmp(self.value, other.value) ... def __init__(self, value): ... self.value = value ... >>> items.sort(key=lambda (x, y): (x, Reverse(y))) >>> items [(1, 3), (1, 2), (1, 1), (2, 3), (2, 2), (2, 1), (3, 1)] Peter -- http://mail.python.org/mailman/listinfo/python-list