问题 如何排序Python对象


我有一个包含不同对象的嵌套列表,它们是嵌套列表中的重复对象对象,我正在尝试删除它们但我一直在

TypeError: unorderable types: 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)

3068
2018-04-23 00:41


起源

通过比较器 key 至 sorted 应该管用。 - Luca


答案:


如果要按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__() 方法。


6
2018-04-23 00:47



第一个选项对我有用......谢谢 - danidee
没问题,我刚刚添加了第二个示例,因为如果您想稍后添加更多功能,它可能会有所帮助 - Padraic Cunningham


要支持在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)

3
2018-04-23 00:53



我试图使用lambda方法,我创建了一个新变量并将其等同于sorted(item,key = lambda x:x.id),但是当我尝试打印出值时,我得到的练习对象是不可迭代的。它不应该是一个清单吗? - danidee
@danidee排序的第一个参数必须是一个可迭代的练习对象。所以试试吧 sorted([practice('b'), practice('a')], key=lambda x: x.id) 例如。它将以下列形式返回一个新列表: [practice('a'), practice('b')] - Shashank