Сортировка по нескольким клавишам с использованием разных порядков

Возможный дубликат:
Как написать ключевые функции сортировки Python для нисходящих значений

В Python 3 довольно легко отсортировать список объектов лексикографически, используя несколько ключей. Например:

items.sort(key = lambda obj: obj.firstname, obj.lastname)

Аргумент reverse позволяет указать, хотите ли вы по возрастанию или по убыванию. Но что вы делаете в случае, если вы хотите сортировать по нескольким клавишам, но хотите сортировать, используя порядок убывания для первого ключа, и порядок возрастания для второго?

Например, предположим, что у нас есть объект с двумя атрибутами, points и name , где points – это int а namestr . Мы хотим отсортировать список этих объектов по points в порядке убывания (так, чтобы сначала был объект с наибольшим числом точек), но для объектов с равным количеством points мы хотим отсортировать их по name в алфавитном порядке (по возрастанию ) заказ.

Как это можно достичь?

Нет никакого встроенного способа справиться с этим. В общем случае вы должны сортировать дважды: сначала по второму типу, затем по первичной сортировке. Как отметил в своем комментарии @Mark Ransom, во многих случаях переменные являются числовыми, поэтому вы можете использовать отрицательное значение для перевода заказа.

Если вы знаете тип переменной, которую вы пытаетесь сортировать и как с ней работать, вы также можете написать ключевую функцию, которая возвращает уменьшающееся значение для увеличения ключей. См. Эту тему для примера для строк. (В принципе, вы берете отрицательное число ASCII числовых символов).

В Python 2 вы также можете использовать функцию cmp вместо ключа, но это, скорее всего, сделает сортировку медленнее. Будет ли это слишком медленным, зависит от того, насколько большой и несортированный список. В Python 3 аргумент cmp исчез, но как примечания @Mark Ransom вы можете использовать cmp_to_key .

 items.sort(key = lambda obj: (obj.firstname, [(-ord(c) for c in obj.lastname)])) 

Существует функция functools.cmp_to_key для преобразования функции сравнения в ключ, совместимый с функциями сортировки. Это было предоставлено для сортировок, которые использовали функцию сравнения в Python 2 и необходимо было преобразовать в Python 3, который больше не позволяет их.

Изменить: В вики Python также есть предложение под заголовком Sort Stability и Complex Sorts, чтобы выполнить сортировку в несколько проходов, от наименее значимого ключа до наиболее значимого. Это работает, потому что сорт Python гарантированно стабилен, поэтому предыдущий порядок сохраняется, когда встречаются эквивалентные ключи.