Python: сортировка списка с несколькими атрибутами и смешанным порядком - PullRequest
19 голосов
/ 04 октября 2009

Я должен отсортировать список Python с несколькими атрибутами. Я могу сделать это в порядке возрастания для всех атрибутов легко с

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

но проблема в том, что я использую смешанные конфигурации для возрастания / убывания ... Я должен немного "подражать" порядку SQL, где вы можете сделать что-то вроде "name ASC, year DESC". Есть ли способ сделать это легко в Python без необходимости реализации пользовательской функции сравнения?

Ответы [ 3 ]

29 голосов
/ 04 октября 2009

Если ваши атрибуты числовые, у вас есть это.

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__. Остальные четыре могут быть получены из этих двух с помощью простой логики.

7 голосов
/ 04 октября 2009

Пользовательская функция сделает ваш код более читабельным. Если у вас много операций сортировки и вы не хотите создавать эти функции, вы можете использовать лямбда-выражения:

L.sort(lambda x, y: cmp(x.name, y.name) or -cmp(x.year, y.year))
6 голосов
/ 04 октября 2009

Вы не можете, но написать функцию сравнения легко:

def my_cmp(a, b):
    return cmp(a.foo, b.foo) or cmp(b.bar, a.bar)
L.sort(my_cmp)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...