开发者

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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜