Допустим, у нас есть список названий деталей и их стоимостей. Нам нужно отсторитровать его сначала по названию деталей, а одинаковые детали по убыванию цены. Самая коротка реализация даст не совсем тот результат:
shop = [['каретка', 1200], ['шатун', 1000], ['седло', 300], ['педаль', 100], ['седло', 1500], ['рама', 12000], ['обод', 2000], ['шатун', 200], ['седло', 2700]]
shop.sort()
for i in range(len(shop)):
    print('{:<10} цена: {:>5}р.'.format(shop[i][0], shop[i][1]))
каретка    цена:  1200р.
обод       цена:  2000р.
педаль     цена:   100р.
рама       цена: 12000р.
седло      цена:   300р.
седло      цена:  1500р.
седло      цена:  2700р.
шатун      цена:   200р.
шатун      цена:  1000р.
Как и следовало ожидать, одинаковые детали отсортированы по возрастанию цены (не обращайте пока внимания на format, или почитайте документацию).

Это можно исправить так:

def prepare_item(item):
    return (item[0], -item[1])

shop = [['каретка', 1200], ['шатун', 1000], ['седло', 300], ['педаль', 100], ['седло', 1500], ['рама', 12000], ['обод', 2000], ['шатун', 200], ['седло', 2700]]
shop.sort(key=prepare_item)
for i in range(len(shop)):
    print('{:<10} цена: {:>5}р.'.format(shop[i][0], shop[i][1]))
каретка    цена:  1200р.
обод       цена:  2000р.
педаль     цена:   100р.
рама       цена: 12000р.
седло      цена:  2700р.
седло      цена:  1500р.
седло      цена:   300р.
шатун      цена:  1000р.
шатун      цена:   200р.
Что здесь произошло? Перед тем, как сравнивать два элемента списка к ним применялась функция prepare_item, которая меняла знак у стоимости. В результате при одинаковов первом значении сортировка по второму происходила в обратном порядке.

Ещё можно писать так (но делать это нужно аккуратно и с пониманием):

shop.sort(key=lambda x: (x[0], -x[1]))

Используя подходящую функцию prepare_item мы можем делать и более сложные сортировки:
Отсортировать только по второму элементу

def prepare_item(item):
    return item[1]
Отсортировать по модулю третьего элемента:
def prepare_item(item):
    return abs(item[2])
Отсортировать сначала по третьему элементу списка, затем по модулю первого:
def prepare_item(item):
    return (item[2], abs(item[0]))
Последнее изменение: Суббота, 15 Август 2020, 02:35