Как отсортировать список словарей по ключу в Python?
Что проверяют
Базовое владение стандартной библиотекой, но с подвохом: интервьюер ждёт не одну строку с lambda, а понимание стабильности сортировки и крайних случаев. Следом почти всегда просят отсортировать по двум ключам в разных направлениях или разобраться с отсутствующим ключом.
Как отвечать
sorted()иlist.sort(): первая возвращает новый список и принимает любой итерируемый объект, второй сортирует на месте и возвращаетNone;- параметр
key: функция вызывается один раз для каждого элемента, а не при каждом сравнении.key=lambda d: d['age']работает, ноoperator.itemgetter('age')короче и немного быстрее; - несколько ключей:
itemgetter('city', 'age')илиlambda d: (d['city'], d['age']). Кортежи сравниваются поэлементно; - разные направления: для чисел достаточно минуса,
key=lambda d: (-d['age'], d['name']). Для строк минус не работает, поэтому пользуются стабильностью: сначала сортируют по второстепенному ключу, потом по главному сreverse=True; - стабильность: сортировка в Python стабильная, элементы с равным ключом сохраняют исходный порядок.
reverse=Trueэту стабильность не нарушает; - пропуски: если ключа может не быть,
d.get('age')вернётNone, а сравнениеNoneс числом в Python 3 падает сTypeError. Выход:key=lambda d: (d.get('age') is None, d.get('age') or 0), записи без значения уйдут в конец; - строки без учёта регистра:
key=lambda d: d['name'].casefold().
Сложность O(n log n), а на частично упорядоченных данных алгоритм работает быстрее за счёт готовых отсортированных участков.
Где спотыкаются
Пишут data = data.sort(key=...). Метод возвращает None, и список теряется.
Не думают про смешанные типы. Одна запись с None или строкой '30' вместо числа роняет сортировку всего списка.
Пытаются перевернуть строковый ключ минусом или сортируют по нескольким ключам вложенными циклами. Две стабильные сортировки подряд решают задачу проще и без ошибок.