Перейти к содержимому
Editor

Сортировка в Python: sort(), sorted(), параметр key и lambda

Средний25 min6 упр.85 XP

Этот урок переведён с английского оригинала.Read in EnglishLeer en españolСообщить об ошибке в переводе

0/6 упр.

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

А теперь представьте, что вы расставили книги по алфавиту. Теперь любая книга находится за секунды. В этом и сила сортировки: она превращает хаос в порядок.

Для сортировки в Python есть два основных инструмента: метод sort() и функция sorted(). Они похожи, но работают по-разному. В этом уроке вы узнаете, когда использовать каждый из них, как сортировать в обратном порядке и как задавать собственные правила сортировки с помощью функций-ключей.

Чем sort() отличается от sorted()?

Это самое важное различие в сортировке на Python. Метод sort() меняет исходный список напрямую. Функция sorted() создаёт совершенно новый отсортированный список, а исходный не трогает.

Представьте это так: sort() переставляет книги на самой полке, а sorted() составляет упорядоченный каталог и оставляет полку в точности такой, какой она была.

sort() меняет список на месте
# sort() modifies the original list
numbers = [5, 2, 8, 1, 9]
numbers.sort()
print(numbers) # [1, 2, 5, 8, 9] - the list itself changed
Вывод
[1, 2, 5, 8, 9]
sorted() создаёт новый список
# sorted() returns a NEW sorted list
numbers = [5, 2, 8, 1, 9]
result = sorted(numbers)
print(result) # [1, 2, 5, 8, 9] - a new list
print(numbers) # [5, 2, 8, 1, 9] - original unchanged!
Вывод
[1, 2, 5, 8, 9]
[5, 2, 8, 1, 9]
Ошибка: присваивание результата sort()
names = ['Charlie', 'Alice', 'Bob']
result = names.sort()
print(result)  # None!
Исправление: sorted() для нового списка
names = ['Charlie', 'Alice', 'Bob']
result = sorted(names)
print(result)  # ['Alice', 'Bob', 'Charlie']

Есть и ещё одно важное отличие: sorted() работает с любым итерируемым объектом, будь то строки, кортежи, словари или даже генераторы. Метод sort() работает только со списками.

sorted() работает с любым итерируемым объектом
# sorted() works on strings too
letters = sorted("python")
print(letters) # ['h', 'n', 'o', 'p', 't', 'y']
# sorted() works on tuples
coords = sorted((3, 1, 4, 1, 5))
print(coords) # [1, 1, 3, 4, 5] - result is always a list
Вывод
['h', 'n', 'o', 'p', 't', 'y']
[1, 1, 3, 4, 5]

Как сортировать в обратном порядке

И sort(), и sorted() принимают параметр reverse. Задайте ему значение True, чтобы сортировать от большего к меньшему, а не от меньшего к большему.

Сортировка по возрастанию и по убыванию
scores = [72, 95, 88, 61, 100]
# Ascending (default)
print(sorted(scores)) # [61, 72, 88, 95, 100]
# Descending
print(sorted(scores, reverse=True)) # [100, 95, 88, 72, 61]
Вывод
[61, 72, 88, 95, 100]
[100, 95, 88, 72, 61]

Строки по умолчанию сортируются по алфавиту. С reverse=True они сортируются в обратном алфавитном порядке.

Сортировка строк в обратном порядке
fruits = ['banana', 'apple', 'cherry', 'date']
print(sorted(fruits)) # ['apple', 'banana', 'cherry', 'date']
print(sorted(fruits, reverse=True)) # ['date', 'cherry', 'banana', 'apple']
Вывод
['apple', 'banana', 'cherry', 'date']
['date', 'cherry', 'banana', 'apple']

Что такое функции-ключи (key) в сортировке Python?

Иногда сортировать нужно не по самим значениям, а по какому-то свойству каждого значения. Например, расставить слова по длине, а не по алфавиту.

Параметр key позволяет передать функцию, которая преобразует каждый элемент перед сравнением. Python применяет эту функцию к каждому элементу, а затем сортирует по полученным результатам. Сами элементы остаются прежними, меняется только порядок.

Сортировка строк по длине с key=len
# Sort words by length instead of alphabetically
words = ['banana', 'pie', 'strawberry', 'kiwi']
result = sorted(words, key=len)
print(result) # ['pie', 'kiwi', 'banana', 'strawberry']
Вывод
['pie', 'kiwi', 'banana', 'strawberry']

Здесь функцией-ключом служит len. Python вызывает len() для каждого слова и по этим длинам определяет порядок. В слове «pie» 3 буквы, в «kiwi» 4, и так далее.

В качестве ключа подойдёт любая функция. Типичный пример: сортировка без учёта регистра с помощью str.lower.

Сортировка без учёта регистра
# Without key - uppercase letters sort before lowercase
names = ['alice', 'Bob', 'CHARLIE', 'dave']
print(sorted(names)) # ['Bob', 'CHARLIE', 'alice', 'dave']
# With key=str.lower - true alphabetical order
print(sorted(names, key=str.lower)) # ['alice', 'Bob', 'CHARLIE', 'dave']
Вывод
['Bob', 'CHARLIE', 'alice', 'dave']
['alice', 'Bob', 'CHARLIE', 'dave']

Как сортировать с помощью lambda-функций

Встроенные функции вроде len и str.lower выручают не всегда. Когда нужна собственная логика сортировки, используют lambda: маленькую анонимную функцию, записанную в одну строку.

Lambda принимает элемент и возвращает значение, по которому нужно сортировать. Синтаксис: lambda item: expression.

Сортировка по последней цифре с помощью lambda
# Sort numbers by their last digit
numbers = [23, 45, 12, 67, 34, 89]
result = sorted(numbers, key=lambda x: x % 10)
print(result) # [12, 23, 34, 45, 67, 89]
Вывод
[12, 23, 34, 45, 67, 89]

Функция lambda x: x % 10 берёт каждое число и возвращает его последнюю цифру (остаток от деления на 10). Затем Python сортирует по этим последним цифрам: 2, 3, 4, 5, 7, 9.

Сортировка по последнему символу
# Sort strings by their last character
words = ['hello', 'zebra', 'apple', 'mango']
result = sorted(words, key=lambda w: w[-1])
print(result) # ['zebra', 'apple', 'mango', 'hello']
Вывод
['zebra', 'apple', 'hello', 'mango']
Сортировка по нескольким критериям с помощью кортежей
# Sort by length first, then alphabetically
words = ['cat', 'bat', 'elephant', 'ant', 'dog']
result = sorted(words, key=lambda w: (len(w), w))
print(result) # ['ant', 'bat', 'cat', 'dog', 'elephant']
Вывод
['ant', 'bat', 'cat', 'dog', 'elephant']

Как сортировать словари и сложные данные

В реальных программах редко сортируют простые списки чисел. Гораздо чаще сортируют списки словарей: например, учеников по оценке или товары по цене.

Сортировка списка словарей по ключу
students = [
{'name': 'Alice', 'grade': 92},
{'name': 'Bob', 'grade': 85},
{'name': 'Charlie', 'grade': 97},
{'name': 'Diana', 'grade': 88},
]
# Sort by grade (ascending)
by_grade = sorted(students, key=lambda s: s['grade'])
for s in by_grade:
print(f"{s['name']}: {s['grade']}")
Вывод
Bob: 85
Diana: 88
Alice: 92
Charlie: 97
Сортировка словарей по убыванию
students = [
{'name': 'Alice', 'grade': 92},
{'name': 'Bob', 'grade': 85},
{'name': 'Charlie', 'grade': 97},
{'name': 'Diana', 'grade': 88},
]
# Sort by grade (highest first)
top_students = sorted(students, key=lambda s: s['grade'], reverse=True)
for s in top_students:
print(f"{s['name']}: {s['grade']}")
Вывод
Charlie: 97
Alice: 92
Diana: 88
Bob: 85

Можно отсортировать и ключи или значения самого словаря. По умолчанию функция sorted() перебирает ключи словаря.

Сортировка ключей и значений словаря
prices = {'banana': 1.20, 'apple': 0.80, 'cherry': 3.50, 'date': 5.00}
# Sort by key (fruit name)
for fruit in sorted(prices):
print(f"{fruit}: ${prices[fruit]}")
print()
# Sort by value (price)
for fruit in sorted(prices, key=lambda f: prices[f]):
print(f"{fruit}: ${prices[f]}")
Вывод
apple: $0.8
banana: $1.2
cherry: $3.5
date: $5.0
Traceback (most recent call last):
  File "<exec>", line 11, in <module>
NameError: name 'f' is not defined

Что такое устойчивая сортировка и почему она важна?

Python использует алгоритм сортировки Timsort, и этот алгоритм устойчивый (стабильный). Это значит, что элементы, равные с точки зрения ключа сортировки, сохраняют исходный порядок.

На практике это очень важно. Если вы сортируете учеников по оценке и у двоих оценки одинаковые, они останутся в том же порядке, в каком были до сортировки.

Устойчивая сортировка сохраняет исходный порядок равных элементов
students = [
{'name': 'Alice', 'grade': 90},
{'name': 'Bob', 'grade': 85},
{'name': 'Charlie', 'grade': 90},
{'name': 'Diana', 'grade': 85},
]
# Sort by grade - ties keep original order
result = sorted(students, key=lambda s: s['grade'])
for s in result:
print(f"{s['name']}: {s['grade']}")
# Bob: 85, Diana: 85, Alice: 90, Charlie: 90
# Bob comes before Diana (original order preserved)
# Alice comes before Charlie (original order preserved)
Вывод
Bob: 85
Diana: 85
Alice: 90
Charlie: 90

Практические упражнения

Отсортируйте список чисел
Напишите код

У вас есть список результатов теста. Выведите их отсортированными от меньшего к большему, а на следующей строке от большего к меньшему.

Используйте sorted(), чтобы исходный список остался без изменений.

scores = [78, 92, 65, 88, 95, 71]
# Print scores low to high
# Print scores high to low
Предскажите вывод: sort() и sorted()
Угадайте вывод

Внимательно прочитайте код ниже. Что он выведет? Вспомните главное отличие sort() от sorted().

Напишите вывод в точности таким, каким его покажет программа.

nums = [3, 1, 4, 1, 5]
result = nums.sort()
print(result)
print(nums)
Отсортируйте слова по длине
Напишите код

Отсортируйте список слов по длине (сначала самые короткие). Если у двух слов одинаковая длина, они должны остаться в исходном порядке.

Выведите отсортированный список.

words = ['elephant', 'cat', 'giraffe', 'ox', 'bear', 'ant']
# Sort by length and print
Исправьте ошибку: сортировка с учётом регистра
Исправьте ошибку

Код ниже пытается отсортировать имена по алфавиту, но имена с заглавной и со строчной буквы перемешиваются неправильно. Исправьте сортировку, чтобы имена шли в настоящем алфавитном порядке независимо от регистра.

Вывод должен быть таким: ['alice', 'Bob', 'Charlie', 'dave', 'Eve']

names = ['Charlie', 'alice', 'Eve', 'dave', 'Bob']
result = sorted(names)
print(result)
Отсортируйте учеников по оценке
Напишите код

Отсортируйте список учеников по оценке, от высшей к низшей. Выведите имя и оценку каждого ученика на отдельной строке (имя, двоеточие, пробел и оценка) в формате: Name: Grade

students = [
{'name': 'Alice', 'grade': 88},
{'name': 'Bob', 'grade': 95},
{'name': 'Charlie', 'grade': 72},
{'name': 'Diana', 'grade': 91},
]
# Sort by grade (highest first) and print each student
Сортировка по нескольким критериям
Напишите код

Отсортируйте список товаров сначала по категории (по алфавиту), а внутри каждой категории по цене (сначала дешёвые).

Выведите каждый товар на отдельной строке (категория, название и цена) в формате: category: name - $price

products = [
{'name': 'Banana', 'category': 'fruit', 'price': 1.20},
{'name': 'Milk', 'category': 'dairy', 'price': 3.50},
{'name': 'Apple', 'category': 'fruit', 'price': 0.80},
{'name': 'Cheese', 'category': 'dairy', 'price': 5.00},
{'name': 'Cherry', 'category': 'fruit', 'price': 4.00},
{'name': 'Yogurt', 'category': 'dairy', 'price': 2.50},
]
# Sort by category, then by price within each category

Похожие уроки

Урок был полезен?