有没有办法重写列表项类中list.max()和list.sort()的“key”函数?

3 投票
2 回答
1335 浏览
提问于 2025-04-17 03:10

我有多个子类,它们都继承自一个父类,这些子类会在一个叫做 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,并重写 maxminsorted 方法呢?

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

撰写回答