有没有办法重写列表项类中list.max()和list.sort()的“key”函数?
我有多个子类,它们都继承自一个父类,这些子类会在一个叫做 instance_of_a_class.value
的地方存储一些东西。我重写了 __cmp__()
方法,以便能够合理地比较这些对象,比如用 ==
、<
、>
等符号。
不过,我的代码中有很多地方需要使用
min(list_of_instances_of_class, key=lambda _: _.value)
或 max(list_of_instances_of_class, key=lambda _: _.value)
,还有偶尔会用到 sorted(...
。
我想知道,是否可以在类中重写一个函数,这样我就不需要在每次调用这些函数时都指定 key
函数,还是说我需要创建一个新的类,继承自 list
,并重写 max
、min
和 sorted
方法呢?
2 个回答
1
不,不能直接这样做。最简单的方法可能是定义一些特定的函数,来代替 min/max/sorted 这些功能。例如:
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)
6
只需要实现一下 __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__
这个方法已经不推荐使用了,你提到的所有函数其实只用到了 __lt__
,而不是其他的比较方法。
如果因为某些原因你真的不能这样比较,你可以尝试这样做:
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)
你可以直接调用 maxval(obj_list)
,而不是 max(obj_list)
,还有 sortval(obj_list)
来进行原地排序,而不是用 obj_list.sort()
。