Сортировка данных в Python: что нужно знать
Как выстроить по порядку элементы списков, множеств, строк, кортежей.


Иллюстрация: Катя Павловская для Skillbox Media
Продолжаем разбираться в нюансах работы с данными в Python. Мы уже успели поговорить о списках, словарях, кортежах и множествах — теперь разберёмся, как доставать из них элементы в любом удобном порядке. В этом нам помогут функции сортировки.
Сортировка — это когда мы упорядочиваем элементы в итерируемом объекте по возрастанию, убыванию или другому критерию. В Python есть два способа сортировки: с помощью встроенной функции sorted() и с использованием метода списков .sort(). Рассмотрим их подробнее.
Содержание
- Основы сортировки в Python
- Примеры сортировки разных итерируемых объектов
- Сортировка списка по возрастанию
- Сортировка по убыванию
- Сортировка по ключу
- Стабильность сортировки
- Резюме

Валерий Линьков
Эксперт Skillbox по компьютерным сетям и кибербезопасности. Автор телеграм-канала «Кудрявый микрофон».
Основы сортировки в Python
Функция sorted() — это универсальный метод сортировки. В качестве обязательного параметра она принимает любой итерируемый объект и возвращает отсортированный список, созданный из его элементов. Эта функция не меняет исходный объект, а создаёт новый.
Синтаксис выглядит так:
sorted(iterable, key=None, reverse=False)
Параметры функции:
- iterable — обязательный. В него передаётся итерируемый объект, который вы хотите отсортировать (список, кортеж, строка, множество, замороженное множество).
- key — необязательный. Функция одного аргумента, которая будет применена к каждому элементу (по умолчанию None).
- reverse — необязательный. По умолчанию sorted() сортирует объект по возрастанию — но если поставить reverse=True, можно расположить элементы в обратном порядке.
Отсортируем список с помощью функции sorted():
l = ['a', 'v', 'r', 'h', 'v', 'c', 'd', 'y', 'g', 'b']
print(sorted(l))
# Результат:
# ['a', 'b', 'c', 'd', 'g', 'h', 'r', 'v', 'v', 'y']
print(l)
# Результат:
# ['a', 'v', 'r', 'h', 'v', 'c', 'd', 'y', 'g', 'b']
Видим, что в результате сортировки появился новый список, а исходный не изменился.
Символы в Python сортируются по таблице элементов ASCII: символ с меньшим значением ASCII будет помещён раньше, чем символ с большим значением.
Для сортировки элементов списка существует метод списков .sort(). В отличие от функции sorted(), он изменяет сам список, в котором он вызван, и не возвращает никакого значения (точнее, возвращает None).
Синтаксис .sort():
list.sort(key=None, reverse=False)
Вместо list нужно указать название списка, к которому применяется метод.
Параметры у метода .sort() необязательные. Они аналогичны параметрам sorted():
- key — определяет небольшую функцию, в качестве аргумента принимающую элемент списка. Для каждого элемента она создаёт ключ сравнения — значение, по которому будут сравниваться эти элементы (по умолчанию — None).
- reverse — булевый аргумент, принимающий значения True или False. Если установлено значение True, список сортируется в обратном порядке (по умолчанию — False).
Рассмотрим на примере, как работает метод .sort():
lst = ['a', 'v', 'r', 'h', 'v', 'c', 'd', 'y', 'g', 'b']
print(lst.sort())
# Результат: None
print(lst)
# Результат:
# ['a', 'b', 'c', 'd', 'g', 'h', 'r', 'v', 'v', 'y']
Как мы видим, метод lst.sort() в результате выполнения вернул None, а сам список lst изменился — теперь его элементы отсортированы по возрастанию.
Важно: сортировать можно только те итерируемые объекты, которые содержат однотипные элементы. Если в списке содержатся элементы разных типов и между ними не определена операция сравнения, при выполнении .sort() или sorted() возникнет исключение TypeError.
Примеры сортировки разных итерируемых объектов
Сортировка строк. Отсортируем строку с помощью функции sorted():
s = sorted('Hello, world!')
print(s)
# Результат выполнения:
# [' ', '!', ',', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
Мы получили список символов, отсортированных в порядке возрастания значений ASCII.
Сортировка кортежа. Так будет выглядеть результат сортировки кортежа, элементы которого — числа:
s = sorted((7, 28, 4, 22, 6, 10, 7, 18))
print(s)
# Результат выполнения:
# [4, 6, 7, 7, 10, 18, 22, 28]
В примере выше мы создали список, в котором числа отсортированы по возрастанию.
Сортировка множества. Результат сортировки множества, состоящего из строк:
s = sorted({'attfgl', '#aghj', '1', '120', '3', '23', '1000', '4g', 'ehklgf', 'b', 'йц'})
print(s)
# Результат выполнения:
# ['#aghj', '1', '1000', '120', '23', '3', '4g', 'attfgl', 'b', 'ehklgf', 'йц']
Результат — отсортированный список строк.
Сортировка словарей. В Python словари — это неупорядоченные структуры данных. В них есть быстрый доступ к элементам по ключу, но непосредственная сортировка элементов невозможна.
Если мы применим функцию sorted() к словарю, то получим отсортированный список ключей кода в случае, когда ключи словаря одного типа. Иначе возникнет ошибка TypeError.
original_dict = {'b': 1, 'a': 2, 'c': 3}
sorted_items = sorted(original_dict)
print(sorted_items) # Результат: ['a', 'b', 'c']
Отсортировать словарь можно с помощью функции sorted() совместно с методом словаря .items(). Этот метод возвращает ключи и значения словаря в виде набора кортежей.
original_dict = {'b': 1, 'a': 2, 'c': 3}
# Сортировка словаря по ключам
sorted_items = sorted(original_dict.items())
print(sorted_items) # [('a', 2), ('b', 1), ('c', 3)]
# Преобразование обратно в словарь
sorted_dict = dict(sorted_items)
print(sorted_dict) # {'a': 2, 'b': 1, 'c': 3}
Сначала мы преобразуем набор кортежей original_dict.items() с помощью функции sorted() в список, отсортированный по ключам. Затем преобразуем список обратно в словарь с помощью функции dict().
Сортировка списка по возрастанию
На направление сортировки влияет необязательный параметр reverse. Если reverse=False (значение по умолчанию), то данные будут сортироваться от большего к меньшему.
Числовые данные. Сортируются по возрастанию их значений:
lst = [10, 8, 14, 0, 5, 4, 6, 29]
lst.sort()
print(lst)
# Результат:
# [0, 4, 5, 6, 8, 10, 14, 29]
Но если мы переведём числовые значения в строки, результат будет другой:
lst = ['10', '8', '14', '0', '5', '4', '6', '29']
lst.sort()
print(lst)
# Результат:
# ['0', '10', '14', '29', '4', '5', '6', '8']
Это происходит потому, что сортируемые строки сравниваются посимвольно, начиная с первого символа. Если пара символов не равна, тогда результатом сравнения строк становится результат сравнения этой пары, например: '5' > '10', а '29' < '6'.
Символьные данные. Сортируются в порядке возрастания значений ASCII: символ с меньшим значением ASCII будет помещён раньше, чем символ с большим значением ASCII.
print(sorted(['a', 'v', 'r', 'A', 'd', 'g', 'b', '0', '2', '#', '%', 'ж', 'й']))
# Результат сортировки:
# ['#', '%', '0', '2', 'A', 'a', 'b', 'd', 'g', 'r', 'v', 'ж', 'й']
Большие и маленькие буквы считаются разными символами (коды ASCII для 'A' и 'a' разные, причём код 'A' меньше, чем код 'a').
Символы, отличные от букв (например, пробелы, знаки пунктуации, символы табуляции), также имеют коды ASCII и участвуют в сортировке.
Булевы значения. False идёт перед True, так как их численные эквиваленты — 0 и 1 соответственно.
booleans = [True, False, True, False, True]
print(sorted(booleans))
# Результат: [False, False, True, True, True]
Сортировка по убыванию
Если параметр reverse = False, то сортировка идёт в обратном порядке — по убыванию элементов:
l = ['a', 'v', 'r', 'h', 'v', 'c', 'd', 'y', 'g', 'b']
print(sorted(l, reverse = True))
# Результат:
# ['y', 'v', 'v', 'r', 'h', 'g', 'd', 'c', 'b', 'a']
l.sort(reverse = True)
print(l)
# Результат тот же:
#['y', 'v', 'v', 'r', 'h', 'g', 'd', 'c', 'b', 'a']
Сортировка по ключу
Ключ сортировки key в Python может быть любой функцией, которая применяется к каждому элементу в списке перед сравнением.
Принцип работы такой: к каждому элементу в списке применяется какая-то функция, а потом результаты этих функций сравниваются для определения порядка элементов.
Разберём несколько примеров.
Сортировка по длине. Если нужно отсортировать список строк в порядке возрастания длины строки, в качестве ключа сортировки используем функцию len.
words = ['cat', 'hamster', 'squirrel', 'rabbit']
sorted_words = sorted(words, key=len)
print(sorted_words)
# Результат:
# ['cat', 'rabbit', 'hamster', 'squirrel']
Слово 'cat' — первое в списке, потому что оно самое короткое, а 'squirrel' — последнее, так как оно самое длинное.
Сортировка c помощью собственной функции. Например, можно создать функцию, которая возвращает последний символ строки, и использовать её в качестве ключа сортировки.
def last_char(s):
return s[-1]
words = ['cat', 'hamster', 'squirrel', 'rabbit']
sorted_words = sorted(words, key=last_char)
print(sorted_words)
# Результат: ['squirrel', 'hamster', 'cat', 'rabbit']
Код сравнивает последние символы строк и сортирует список по их возрастанию.
Сортировка с помощью лямбда-функции. lambda в Python — это анонимная функция, принимающая любое количество аргументов, но имеющая только одно выражение, которое выполняется и возвращает результат. В качестве ключа сортировки используется функция с одним аргументом.
Ключ сортировки особенно полезен, когда нам нужно сортировать сложные структуры данных — например, списки словарей.
people = [
{'name': 'Helen', 'age': 24},
{'name': 'John', 'age': 21},
{'name': 'Sam', 'age': 19}
]
sorted_people = sorted(people, key=lambda p: p['age'])
print(sorted_people)
# Результат: [{'name': 'Sam', 'age': 19}, {'name': 'John', 'age': 21}, {'name': 'Helen', 'age': 24}]
В этом примере мы используем лямбда-функцию lambda p: p['age'], которая возвращает возраст каждого человека, и таким образом сортируем записи о людях в порядке увеличения их возраста.
Сортировка со встроенными функциями. В Python есть встроенные функции, которые можно использовать в качестве ключей. Например, функцию abs можно использовать для сортировки чисел не по их реальному, а по абсолютному значению. Абсолютное значение — это его величина без учёта знака. Например, абсолютное значение числа 5 равно 5, а абсолютное значение числа −3 равно 3.
numbers = [1, -2, 3, -4, -5]
sorted_numbers = sorted(numbers, key=abs)
print(sorted_numbers) # Результат: [1, -2, 3, -4, -5]
Стабильность сортировки
Сортировка в Python по умолчанию является стабильной. Это относится и функции sorted(), и к методу .sort().
Стабильность означает, что, когда два элемента имеют одинаковые ключи сортировки, их относительный порядок сохраняется. Это важно при последовательной сортировке — например, если у нас есть список, включающий в себя элементы с двумя и более полями. Если мы сначала отсортируем список по второму полю, а затем по первому, то порядок сортировки по второму полю сохранится.
Например:
color = [('green', 3), ('red', 1), ('blue', 2), ('green', 1), ('red', 2), ('blue', 1), ('green', 2)]
sorted_color = sorted(color, key=lambda x: x[1]) # Сортируем по второму ключу
print(sorted_color)
# Результат: [('red', 1), ('green', 1), ('blue', 1), ('blue', 2), ('red', 2), ('green', 2), ('green', 3)]
sorted_color = sorted(sorted_color, key=lambda x: x[0]) # Сортируем по первому ключу
print(sorted_color)
# Результат: [('blue', 1), ('blue', 2), ('green', 1), ('green', 2), ('green', 3), ('red', 1), ('red', 2)]
Сначала мы сортируем список кортежей по второму элементу (номеру) в порядке возрастания — от 1 до 3. Затем сортируем по первому ключу — color.
Поскольку 'blue' меньше, чем 'green' и 'red', все кортежи 'blue' стоят первыми, затем идут кортежи 'green', а после — 'red'. Но внутри каждой группы кортежей с одинаковым первым элементом порядок остался таким же, как после первой сортировки (по номеру). Это показывает стабильность сортировки.
Резюме
- Любые итерируемые объекты в Python можно сортировать с помощью функции sorted(), а списки — с помощью метода .sort(). Функция sorted() возвращает отсортированный список, состоящий из элементов итерируемого объекта, а сам объект не меняется. Метод списка .sort() изменяет сам список.
- По умолчанию сортировка происходит в порядке возрастания, но можно провести и в обратном — с помощью аргумента reverse, которому нужно передать значение True.
- Чтобы определить свои собственные критерии сортировки, можно использовать ключ сортировки.
- Разные структуры данных требуют разных методов сортировки, поэтому всегда стоит заранее обдумать, какие данные предстоит сортировать и каким методом. При работе с большим объёмом данных нужно учитывать, что одни методы могут быть более эффективными, чем другие.
- Например, если нужно только отсортировать список, не сохраняя его оригинальное значение, то лучше использовать метод .sort() — это сэкономит память. Если же при сортировке нужно сохранить исходный объект, то используется функция sorted().
Больше интересного про код — в нашем телеграм-канале. Подписывайтесь!