On 12/20/2010 7:10 PM, Chris Rebert wrote: > On Mon, Dec 20, 2010 at 3:23 PM, <pythonlist.cali...@spamgourmet.com> wrote: >> Hi all - it would seem that these days, all the cool kids use the sort >> function's 'key' kwarg in order to sort a list of custom objects quickly. > > Really? They don't bother to define __cmp__ or similar? Sounds lazy > and poorly structured. > That sounds to me like a potentially ill-informed response.
>> Unfortunately, as opposed to using 'cmp', where you can implent __cmp__ to >> get 'automatic sorting' in a similar fashion, there doesn't seem to be a >> direct analogue for a class-overridable method for providing a sort key. >> (ie, something like '__sortkey__' or '__key__'). > Why do you talk about "implementing __cmp__"? Why should this be necessary? > Just simply delegate to key comparison in your __cmp__ (or similar) method(s). > Assuming, of course, that you are conveniently sorting only object over which you have complete control ... >> Is there one, and I'm just missing it? If not, are there any plans to add >> one? (I did a quick search of the PEP list, and the only hits for 'sort' I >> saw had to do with sorting dictionaries by value). > > If you know at class-definiton-time how you want instances to be > sorted, then just define __cmp__ (or the rich comparison methods) > appropriately, possibly even delegating to a comparison of keys (as > the class defines them). > > For example: > > from functools import total_ordering > > @total_ordering > class Person(object): > def __init__(self, first_name, last_name): > self.first_name = first_name > self.last_name = last_name > > @property > def _key(self): > """Identifying key for a Person, by which they are sorted""" > return (self.last_name, self.first_name) > > def __eq__(self, other): > return isinstance(other, Person) and self._key == other._key > > def __lt__(self, other): > return self._key < other._key > > If you want to abstract even this away, then just write a class > decorator; there's no need to add yet another (rather complicated due > to all the interactions with the existing comparison methods) special > method. > But the *real* point is (as the documentation attempts to point out) that by providing the key argument it gets called only once per element, whereas the cmp argument (or the objects' __cmp__() method if you insist on letting sort delegate to that) gets called every time two objects have to be compared. If cmp is a Python function (or equivalently if __cmp__() is a Python method) then calling it will take much longer than calling hte built-in default routines. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 PyCon 2011 Atlanta March 9-17 http://us.pycon.org/ See Python Video! http://python.mirocommunity.org/ Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list