Модуль 6 · Функции и модули

Справочник по Python · модуль 6 · функции и модули

Глава 6.10

6.10

sort(), sorted()
и параметр key

sort() меняет сам список, sorted() создаёт новый, а key объясняет Python, по какому признаку сравнивать сложные элементы.

Категория
Сортировка коллекций
Уровень
Средний
Связанные темы
Списки, lambda, функции
Зачем это знать
Упорядочивать данные по одному или нескольким признакам

§1Два способа сортировки

ИнструментКакие данные принимаетИсходный объектРезультат
list.sort()только списокизменяетсяNone
sorted(iterable)любой итерируемый объектне изменяетсяновый список

§2Метод list.sort()

main.pyизменение исходного списка
numbers = [4, 1, 3, 2]
result = numbers.sort()
print(numbers)
print(result)
Выводсписок и результат метода
[1, 2, 3, 4]
None

§3Функция sorted()

main.pyновый список
numbers = [4, 1, 3, 2]
ordered = sorted(numbers)
print(ordered)
print(numbers)
print(sorted("cab"))
Выводисходный список сохранён
[1, 2, 3, 4]
[4, 1, 3, 2]
['a', 'b', 'c']

§4Как работает key

key принимает функцию. Для каждого элемента Python один раз вычисляет ключ, сортирует по ключам и возвращает исходные элементы в новом порядке.

Схемаэлемент сохраняется целиком
sorted(items, key=function)

элемент → function(элемент) → ключ сравнения
"python" → len("python")   → 6

§5Сортировка строк по длине

main.pyготовая функция len как key
words = ["яблоко", "груша", "банан", "слива"]
print(sorted(words, key=len))
Выводравные длины сохраняют порядок
['груша', 'банан', 'слива', 'яблоко']

§6Сложные элементы

Lambda-функция извлекает нужную часть кортежа или словаря.

main.pyкортеж по второму элементу
data = [(1, 3), (4, 1), (2, 2)]
print(sorted(data, key=lambda item: item[1]))
Выводключи 3, 1 и 2
[(4, 1), (2, 2), (1, 3)]
main.pyсловари по возрасту
people = [{"name": "Макс", "age": 22}, {"name": "Анна", "age": 19}]
ordered = sorted(people, key=lambda person: person["age"])
print(ordered)

§7Несколько критериев

Кортеж-ключ сравнивается слева направо: сначала первый критерий, при равенстве — второй.

main.pyсначала класс, затем имя
students = [(9, "Вера"), (8, "Борис"), (9, "Анна")]
ordered = sorted(students, key=lambda item: (item[0], item[1]))
print(ordered)
Выводкортеж ключей
[(8, 'Борис'), (9, 'Анна'), (9, 'Вера')]

§8Обратный порядок

reverse=True разворачивает итоговый порядок после применения key.

main.pyпо убыванию
numbers = [1, 5, 3, 2]
print(sorted(numbers, reverse=True))
Выводот большего к меньшему
[5, 3, 2, 1]

§9Стабильная сортировка

Если ключи равны, Python сохраняет относительный порядок элементов. Поэтому среди слов одинаковой длины раньше останется то, которое раньше находилось в исходных данных.

main.pyодинаковый балл
results = [("Анна", 5), ("Борис", 4), ("Вера", 5)]
print(sorted(results, key=lambda item: item[1], reverse=True))
ВыводАнна остаётся перед Верой
[('Анна', 5), ('Вера', 5), ('Борис', 4)]

§10Параметр key в min() и max()

Тот же принцип применяется при выборе одного элемента. Возвращается исходный элемент, а не вычисленный ключ.

main.pyкороткое и длинное слово
words = ["яблоко", "груша", "слива"]
print(min(words, key=len))
print(max(words, key=len))
Выводпри равенстве выбирается первое
груша
яблоко

§11Частые ошибки

Что написаноЧто произойдётКак правильно
ordered = numbers.sort()в ordered попадёт None, а список изменитсяnumbers.sort() или ordered = sorted(numbers)
sorted(words, key=len())len() вызывается без аргумента заранееsorted(words, key=len)
sorted(data, lambda x: x[1])TypeError: key передаётся по имениsorted(data, key=lambda x: x[1])
ожидать от sorted(text) строкуполучится список отдельных символов"".join(sorted(text))
функция key возвращает несравнимые типыво время сортировки возможен TypeErrorвозвращать ключи согласованного типа

§12Проверьте себя

Какой инструмент меняет исходный список?

Метод list.sort(). Функция sorted() возвращает новый список.

Что возвращает функция key?

Ключ сравнения для одного элемента; в итоговую коллекцию всё равно попадает исходный элемент.

Что происходит с элементами, у которых равные ключи?

Благодаря стабильности сортировки они сохраняют взаимный порядок.

§13Шпаргалка

Изменить списокitems.sort(key=rule)
Новый списокsorted(items, key=rule)
По убываниюreverse=True
Несколько критериевkey=lambda x: (x[0], x[1])

Итог главы

list.sort() изменяет список и возвращает None, а sorted() принимает любой итерируемый объект и создаёт новый список. Функция key один раз вычисляет признак каждого элемента; кортеж позволяет задать несколько критериев, а стабильность сохраняет порядок равных ключей.

Глава 6.10 · Сортировка и key · Справочник по PythonАвтор: Макаров Максим Николаевич