Справочник по Python · модуль 6 · функции и модули
Глава 6.10
sort(), sorted()
и параметр key
sort() меняет сам список, sorted() создаёт новый, а key объясняет Python, по какому признаку сравнивать сложные элементы.
- Категория
- Сортировка коллекций
- Уровень
- Средний
- Связанные темы
- Списки, lambda, функции
- Зачем это знать
- Упорядочивать данные по одному или нескольким признакам
§1Два способа сортировки
| Инструмент | Какие данные принимает | Исходный объект | Результат |
|---|---|---|---|
list.sort() | только список | изменяется | None |
sorted(iterable) | любой итерируемый объект | не изменяется | новый список |
§2Метод list.sort()
numbers = [4, 1, 3, 2] result = numbers.sort() print(numbers) print(result)
[1, 2, 3, 4] None
§3Функция sorted()
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Сортировка строк по длине
words = ["яблоко", "груша", "банан", "слива"] print(sorted(words, key=len))
['груша', 'банан', 'слива', 'яблоко']
§6Сложные элементы
Lambda-функция извлекает нужную часть кортежа или словаря.
data = [(1, 3), (4, 1), (2, 2)] print(sorted(data, key=lambda item: item[1]))
[(4, 1), (2, 2), (1, 3)]
people = [{"name": "Макс", "age": 22}, {"name": "Анна", "age": 19}]
ordered = sorted(people, key=lambda person: person["age"])
print(ordered)§7Несколько критериев
Кортеж-ключ сравнивается слева направо: сначала первый критерий, при равенстве — второй.
students = [(9, "Вера"), (8, "Борис"), (9, "Анна")] ordered = sorted(students, key=lambda item: (item[0], item[1])) print(ordered)
[(8, 'Борис'), (9, 'Анна'), (9, 'Вера')]
§8Обратный порядок
reverse=True разворачивает итоговый порядок после применения key.
numbers = [1, 5, 3, 2] print(sorted(numbers, reverse=True))
[5, 3, 2, 1]
§9Стабильная сортировка
Если ключи равны, Python сохраняет относительный порядок элементов. Поэтому среди слов одинаковой длины раньше останется то, которое раньше находилось в исходных данных.
results = [("Анна", 5), ("Борис", 4), ("Вера", 5)] print(sorted(results, key=lambda item: item[1], reverse=True))
[('Анна', 5), ('Вера', 5), ('Борис', 4)]§10Параметр key в min() и max()
Тот же принцип применяется при выборе одного элемента. Возвращается исходный элемент, а не вычисленный ключ.
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=Truekey=lambda x: (x[0], x[1])Итог главы
list.sort() изменяет список и возвращает None, а sorted() принимает любой итерируемый объект и создаёт новый список. Функция key один раз вычисляет признак каждого элемента; кортеж позволяет задать несколько критериев, а стабильность сохраняет порядок равных ключей.