[Tutor] lazily decorated sort

Peter Otten __peter__ at web.de
Fri Sep 28 21:34:55 CEST 2012


eryksun wrote:

> On Fri, Sep 28, 2012 at 8:17 AM, Peter Otten <__peter__ at web.de> wrote:
>>
>> def make_key(keys):
>>     @total_ordering
>>     class Key(object):
>>         def __init__(self, value):
>>             self._keys = keys(value)
>>             self._cached = []
> 
> 
> Using a generator/iterator to pump the key values into a cache is a
> great idea. But I think it would generally be nicer to let "keys" be a
> sequence of functions. Then define the generator in make_key() before
> you define the class:

I should have mentioned that make_key() may be used as a decorator. So it is

@make_key
def key(value):
    yield value
    yield f(value)
    yield value.attrib
items.sorted(key=key)

against (assuming the signature make_key(*keyfuncs))

items.sort(key=make_key(
    lambda value: value,
    f,
    operator.itemgetter("attrib"))
)

I think the first version looks a bit cleaner, but that's a matter of taste.

> Also, as far as I can see in the code, implementing "total_ordering"
> is unnecessary for sorting. One only needs to implement __lt__. It's
> used by binarysort() to test the pivot via the IFLT/ISLT macros:
> 
> http://hg.python.org/cpython/file/70274d53c1dd/Objects/listobject.c#l1023

I smell danger. I really don't like having a class lying around that 
partially implements ordering and may fail where you least expect it.

>>                  if a == b:
>>                      pass
>>                  else:
>>                      return a < b

> Or test for "!=":

Yes, that was odd indeed.




More information about the Tutor mailing list