多属性混合顺序的列表排序

22 投票
3 回答
15882 浏览
提问于 2025-04-15 14:47

我需要对一个包含多个属性的列表进行排序。我可以很简单地用下面的代码把所有属性按升序排列:

L.sort(key=operator.attrgetter(attribute))....

但问题是,我需要混合使用升序和降序的排序方式……我想要有点像SQL中的Order By,比如可以写成name ASC, year DESC。有没有什么简单的方法在Python中做到这一点,而不需要自己写比较函数呢?

3 个回答

7

你不能这样做,不过写一个比较函数其实很简单:

def my_cmp(a, b):
    return cmp(a.foo, b.foo) or cmp(b.bar, a.bar)
L.sort(my_cmp)
8

自定义函数可以让你的代码更容易阅读。如果你有很多排序的操作,但又不想一个个去写这些函数,你可以使用lambda表达式:

L.sort(lambda x, y: cmp(x.name, y.name) or -cmp(x.year, y.year))
34

如果你的属性是数字类型,那你就可以直接使用这个。

def mixed_order( a ):
    return ( a.attribute1, -a.attribute2 )

someList.sort( key=mixed_order )

如果你的属性包含字符串或者其他更复杂的对象,那你就有一些选择。

.sort() 方法是稳定的:你可以进行多次排序。这可能是最简单的方法,而且速度也非常快。

def key1( a ): return a.attribute1
def key2( a ): return a.attribute2

someList.sort( key=key2, reverse=True )
someList.sort( key=key1 )

如果这是唯一的排序,你可以定义自己专用的比较操作符。至少你需要 __eq____lt__ 这两个。其他四个可以通过这两个简单的逻辑推导出来。

撰写回答