Is there a way to override the "key" function for list.max() and list.sort() in the class of the list items?
I have multiple subclasses of a superclass that store something in a instance_of_a_class.value
and I override __cmp__()
to provide reasonable 开发者_如何学编程==
, <
, >
etc. comparisons.
However, I have multiple places in my code where I do
min(list_of_instances_of_class, key=lambda _: _.value)
or max(list_of_instances_of_class, key=lambda _: _.value)
and an occasional sorted(...
Is there a function to override in the class so that I don't have to specify the key
function for each call to the said functions or do I need to subclass list
and override the max
, min
and sorted
methods?
Just implement __lt__
:
class Obj(object):
def __init__(self, value):
self.value = value
def __lt__(self, other):
return self.value < other.value
def __repr__(self):
return 'Obj(%r)' % self.value
obj_list = [Obj(2), Obj(1), Obj(4), Obj(3)]
print max(obj_list)
print min(obj_list)
print sorted(obj_list)
__cmp__
is deprecated, and all of the functions that you mentioned use only __lt__
not the other comparisons.
If for some reason you really can't have them compare this way, you can do something like:
from operator import attrgetter
from functools import partial
valget = attrgetter('value')
maxval = partial(max, key=valget)
minval = partial(max, key=valget)
sortedval = partial(sorted, key=valget)
sortval = partial(list.sort, key=valget)
Where you call them just as maxval(obj_list)
instead of max(obj_list)
etc., and sortval(obj_list)
to sort in-place instead of obj_list.sort()
Not directly, no. The simplest thing would probably be to define specific functions that you use in place of min/max/sorted. e.g.
from functools import partial
min_myclass = partial(min, key = operator.attrgetter('value'))
max_myclass = partial(max, key = operator.attrgetter('value'))
...
min_myclass(list_of_instances_of_myclass)
精彩评论