如何对Python对象进行排序

11

我有一个嵌套列表,其中包含不同的对象,它们是嵌套列表中的重复对象对,我试图将它们删除,但一直收到错误信息

TypeError: 不可排序类型:practice() < practice()

我知道这个错误是由于我尝试使用对象而不是整数来处理导致的,但我不知道其他方法如何去掉重复项,以下是我尝试过的:

class practice:
    id = None

    def __init__(self,id):
        self.id = id

a = practice('a')
b = practice('b')
c = practice('c')
d = practice('d')
e = practice('e')
f = practice('f')

x = [[a,b],[c,d],[a,b],[e,f],[a,b]]

unique_list = list()
for item in x:
    if sorted(item) not in unique_list:
        unique_list.append(sorted(item))

print(unique_list)

2
传递一个比较器“key”给“sorted”应该可以工作。 - Luca
2个回答

6
如果您想通过ID比较对象:
class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return other.id > self.id

    def __gt__(self, other):
        return self.id > other.id

unique_list = list()
for item in x:
    if sorted(item) not in unique_list:
        unique_list.append(sorted(item))

print(unique_list)
[[<__main__.practice object at 0x7fe87e717c88>, <__main__.practice object at 0x7fe87e717cc0>],
 [<__main__.practice object at 0x7fe86f5f79e8>, <__main__.practice object at 0x7fe86f589278>],
 [<__main__.practice object at 0x7fe86f589be0>, <__main__.practice object at 0x7fe86f589c18>]]

根据您想要实现的功能,您可以使用functools.total_ordering来使用所有丰富比较排序方法,您只需要定义其中一个方法,它将负责其余的操作。

from functools import total_ordering
@total_ordering
class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return other.id > self.id

    def __eq__(self, other):
        return self.id == other.id

给定一个定义了一个或多个比较方法的类,这个类装饰器提供了其余的方法。这简化了指定所有可能的比较运算所需的工作:
该类必须定义其中之一:`__lt__()`、`__le__()`、`__gt__()`或`__ge__()`。此外,该类应该提供一个`__eq__()`方法。

没问题,我刚刚添加了第二个示例,如果您以后想要添加更多功能,它可能会有所帮助。 - Padraic Cunningham

3
为了支持Python 3中对象的无显式键排序,您必须实现__lt__特殊方法:
class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return self.id < other.id

如果您想让其他运算符也起作用,您还需要实现它们的特殊方法,但对于排序而言,只需要__lt__即可。
正如评论中所指出的那样,另一种方法是为内置的sorted提供一个明确的键函数。
sorted(item, key=lambda x: x.id)

我试图使用lambda方法,创建了一个新变量并将其赋值为sorted(item, key=lambda x: x.id),但是当我尝试打印出该值时,我得到了“practice object is not iterable”的错误。难道它不应该是一个列表吗? - danidee
@danidee sorted的第一个参数必须是一个练习对象的可迭代对象。因此,例如尝试sorted([practice('b'), practice('a')], key=lambda x: x.id)。它将返回一个新列表,形式为:[practice('a'), practice('b')] - Shashank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接