有没有什么方法可以不用cmp sort参数对大型对象进行排序?

2024-06-25 23:09:48 发布

您现在位置:Python中文网/ 问答频道 /正文

当我使用外部API时,它会将我转储到一个数组中,其中每个元素都是一个包含许多键的字典。随着Python3中cmp参数的弃用,我是否被迫编写这样的类

@total_ordering
class SomeClass(object):
    def __init__(self, field1, field2, field3, field4, ..., field100):
        self.field1 = field1
        self.field2 = field2
        self.field3 = field3
        self.field4 = field4
        ...
        self.field100 = field100

    def __lt__(self, other):
        # some complex way to do ordering
        a = self.field3 * self.field4 - self.field5
        b = other.field3 * other.field4 - other.field5
        return a < b

我这里的问题是被迫把这个大字典变成一个类对象,如果我想要所有的值,我就必须编写这么长的构造函数。这将在Python2中完成:

def compare(a, b):
    # some complex way to do ordering
    a = self.field3 * self.field4 - self.field5
    b = other.field3 * other.field4 - other.field5
    return a < b

sorted([dict1, dict2, ..., dict1000], cmp=compare)

Tags: toselfdefsomewayothercmpcomplex
1条回答
网友
1楼 · 发布于 2024-06-25 23:09:48

Python的sort只使用__lt__,因此如果您只想对对象进行排序,就不需要定义__eq____ne__

但大多数人会使用可选的key=参数:

array_of_those_things.sort(key=lambda x: x.field2)

这样它也会运行得更快—而不是在每个O(N*log(N))比较中查找field2两次,key=参数将导致sort()从列表中的每个对象中检索field2,并在整个排序过程中使用缓存值

您还将看到以下内容:

import operator
array_of_those_things.sort(key=operator.itemgetter("field2"))

顺便说一句,我在这里给出的代码实际上可能不起作用,因为您没有显示如何访问原始对象的字段,只是在将对象填充到某个人工类之后如何访问字段。因此,必须根据原始对象的实际行为调整key=函数

懒惰但不推荐

在Python2的任何一个例子中

somelist.sort(cmp=f)

您可以在Python 3中执行以下操作:

from functools import cmp_to_key
somelist.sort(key=cmp_to_key(f))

但这在几乎所有情况下都是毫无必要的低效。实际上,python2中的cmp=本身通常是不必要的低效。如果可能的话,可以按预期使用python3的key=。但在你给出原始数据的精确细节之前,我猜不出它们是什么;-)

相关问题 更多 >