繁体   English   中英

如何对包含用户定义对象的列表列表进行排序

[英]How to sort list of lists containing user defined objects

我在一个名为"category_tree"的变量中有以下"category"对象列表,这是一个列表:

[[<Category: State>, <Category: County>, <Category: Chicago>], 
[<Category: Animal>],
[<Category: State>, <Category: County>], 
[<Category: State>, <Category: County>, <Category: NYC>], 
[<Category: Animal>, <Category: Fish>], 
[<Category: State>, <Category: County>, <Category: LA>], 
[<Category: Animal>, <Category: Frog>, <Category: TreeFrog>, <Category: Fred>]]

我需要按底层lists.name属性对顶级list进行排序。 我不想对底层列表进行排序,只对顶级list进行排序。

假设.name元素与此处列出的内容匹配,这就是我想要得到的:

[[<Category: Animal>], 
[<Category: Animal>, <Category: Fish>], 
[<Category: Animal>, <Category: Frog>, <Category: TreeFrog>, <Category: Fred>]
[<Category: State>, <Category: County>], 
[<Category: State>, <Category: County>, <Category: Chicago>],
[<Category: State>, <Category: County>, <Category: LA>], 
[<Category: State>, <Category: County>, <Category: NYC>]]

我可以按第一列或最后一列对它们进行排序:

category_tree.sort(key=lambda x: x[0].name)
category_tree.sort(key=lambda x: x[-1].name)

但是我遇到的问题是它们有可变数量的列,所以我不能对所有内部列进行这种排序。

做这个的最好方式是什么?

一个稍微修改的例子,有一个可能的解决方案:

class Category:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return self.name

items = [
    [Category('State'), Category('County'), Category('Chicago')],
    [Category('Animal')],
    [Category('State'), Category('County')],
    [Category('Animal'), Category('Frog')],
    [Category('Animal'), Category('Fish'), Category('Dog')],
]

items.sort(key=lambda x: [item.name for item in x])
print(items)

结果是

[[Animal], [Animal, Fish, Dog], [Animal, Frog], [State, County], [State, County, Chicago]]

这依赖于 Python 直接比较列表的能力,前提是可以正确比较列表中的各个项目。 对于整数、浮点数和字符串,这不是问题。 对于(基本)class,它是,因为它没有默认定义。

如果您有权访问Category class(即,您自己编写),您可以覆盖__eq__和其他神奇的比较方法,这会使事情变得更简单(参见例如比较 object 实例的属性是否相等)。

functools模块的帮助下:

from functools import total_ordering

@total_ordering 
class Category:
    def __init__(self, name):
        self.name = name

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

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

    def __repr__(self):
        return self.name

然后简单地说:

items.sort()

items如前)。

结果相同: [[Animal], [Animal, Fish, Dog], [Animal, Frog], [State, County], [State, County, Chicago]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM