Python: уроки, справочник и задачи

Метод sort() для сортировки списков в Python

Раздел: Списки, кортежи и множества · Обновлено 31.10.2026

Метод list sort в Python упорядочивает элементы списка прямо на месте, без создания копии. Ниже разобраны параметры key и reverse, сортировка чисел, строк, кортежей и словарей, отличие от функции sorted() и типичные ошибки, из-за которых результат получается не тем, что ожидалось.

Метод sort() для сортировки списков в Python
Фото: Nda2120 / CC BY-SA 4.0, Wikimedia Commons
Содержание статьи
  1. Синтаксис и поведение list.sort()
  2. Сортировка по убыванию
  3. Параметр key: собственный критерий сравнения
    1. Строки по длине и без учета регистра
    2. Кортежи и словари
    3. Функции модуля operator
  4. Сортировка по нескольким полям
  5. Чем sort() отличается от sorted()
  6. Типичные ошибки при сортировке
  7. Частые вопросы
    1. Почему print(lst.sort()) выводит None?
    2. Можно ли отсортировать кортеж или строку методом sort()?
    3. Как отсортировать список по убыванию без reverse?
    4. Сохраняется ли порядок одинаковых элементов?
    5. Что быстрее, sort() или sorted()?

Синтаксис и поведение list.sort()

Метод вызывается у самого списка и меняет его содержимое. По умолчанию элементы выстраиваются по возрастанию: числа от меньшего к большему, строки в порядке кодов символов Unicode.

prices = [470, 120, 990, 305, 58]
prices.sort()
print(prices)  # [58, 120, 305, 470, 990]

Полная сигнатура выглядит так: list.sort(*, key=None, reverse=False). Звездочка означает, что оба параметра передаются только по имени. Запись prices.sort(True) вызовет TypeError, правильно писать prices.sort(reverse=True).

ПараметрПо умолчаниюНазначение
keyNoneФункция одного аргумента, результат которой используется для сравнения
reverseFalseПри True порядок становится убывающим

Метод возвращает None, а не отсортированный список. Это сделано намеренно, чтобы было видно: изменился исходный объект. Если нужна новая последовательность, а оригинал должен остаться прежним, используют функцию sorted().

Сортировка по убыванию

Для обратного порядка достаточно передать reverse=True. Параметр работает с любым типом элементов, которые умеют сравниваться между собой.

scores = [72, 95, 64, 88]
scores.sort(reverse=True)
print(scores)  # [95, 88, 72, 64]

letters = ['e', 'a', 'u', 'o', 'i']
letters.sort(reverse=True)
print(letters)  # ['u', 'o', 'i', 'e', 'a']

Не путайте reverse=True с методом reverse(). Первый сортирует по убыванию, второй просто переворачивает текущий порядок элементов, ничего не сравнивая. Другие методы и их отличия собраны в обзоре методов списка.

Параметр key: собственный критерий сравнения

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

Строки по длине и без учета регистра

Заглавные латинские буквы имеют меньшие коды, чем строчные, поэтому без ключа 'Zebra' окажется раньше 'apple'. Ключ str.lower выравнивает регистр только для сравнения.

words = ['banana', 'Kiwi', 'apple', 'Fig']
words.sort()
print(words)  # ['Fig', 'Kiwi', 'apple', 'banana']

words.sort(key=str.lower)
print(words)  # ['apple', 'banana', 'Fig', 'Kiwi']

words.sort(key=len)
print(words)  # ['Fig', 'Kiwi', 'apple', 'banana']

Кортежи и словари

Кортежи без ключа сравниваются поэлементно: сначала первые элементы, при равенстве вторые и так далее. Чтобы сортировать по конкретному полю, его возвращают из лямбды. Синтаксис анонимных функций подробно описан в статье про lambda в Python.

points = [(2, 2), (3, 4), (4, 1), (1, 3)]
points.sort(key=lambda p: p[1])
print(points)  # [(4, 1), (2, 2), (1, 3), (3, 4)]

employees = [
    {'name': 'Alan', 'age': 25, 'salary': 10000},
    {'name': 'Sharon', 'age': 30, 'salary': 8000},
    {'name': 'John', 'age': 18, 'salary': 1000},
]
employees.sort(key=lambda e: e['salary'], reverse=True)
print([e['name'] for e in employees])  # ['Alan', 'Sharon', 'John']

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

Функции модуля operator

Вместо лямбд можно использовать itemgetter и attrgetter. Они работают чуть быстрее и умеют принимать несколько полей сразу.

from operator import itemgetter

rows = [('Ivan', 'B', 90), ('Olga', 'A', 85), ('Petr', 'A', 92)]
rows.sort(key=itemgetter(1, 2))
print(rows)
# [('Olga', 'A', 85), ('Petr', 'A', 92), ('Ivan', 'B', 90)]

Сортировка по нескольким полям

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

students = [('Anna', 5, 19), ('Boris', 4, 20), ('Vera', 5, 18)]
# оценка по убыванию, затем возраст по возрастанию
students.sort(key=lambda s: (-s[1], s[2]))
print(students)
# [('Vera', 5, 18), ('Anna', 5, 19), ('Boris', 4, 20)]

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

staff = [('Lee', 'IT'), ('Adams', 'HR'), ('Brown', 'IT'), ('Clark', 'HR')]
staff.sort(key=lambda s: s[0])                 # имя по возрастанию
staff.sort(key=lambda s: s[1], reverse=True)   # отдел по убыванию
print(staff)
# [('Brown', 'IT'), ('Lee', 'IT'), ('Adams', 'HR'), ('Clark', 'HR')]

Внутри CPython работает алгоритм на основе Timsort со сложностью O(n log n). На почти упорядоченных данных он заметно быстрее, потому что находит уже отсортированные участки и сливает их.

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

Оба инструмента принимают одинаковые key и reverse и дают один и тот же порядок. Разница в том, что происходит с исходными данными и что возвращается.

list.sort()sorted()
Где определенМетод спискаВстроенная функция
Исходные данныеИзменяютсяОстаются без изменений
РезультатNoneНовый список
Что принимаетТолько списокЛюбой итерируемый объект: кортеж, строку, множество, словарь
ПамятьКопия не создаетсяНужна память под новый список
data = [3, 1, 2]
result = sorted(data)
print(data, result)   # [3, 1, 2] [1, 2, 3]

print(sorted('python'))  # ['h', 'n', 'o', 'p', 't', 'y']

Если исходный список дальше не нужен, выбирайте sort(): экономится память. Если оригинал нужно сохранить или на входе не список, берите sorted(). Больше приемов работы с этим типом данных есть в разделе о работе со списками.

Типичные ошибки при сортировке

Большинство проблем связано с тем, что ожидания от сравнения элементов не совпадают с тем, как сравнивает Python.

nums = ['10', '9', '2', '33']
nums.sort(key=int)
print(nums)  # ['2', '9', '10', '33']

cities = ['Ёлкино', 'Анапа', 'Яхрома']
cities.sort(key=lambda w: w.lower().replace('ё', 'е'))
print(cities)  # ['Анапа', 'Ёлкино', 'Яхрома']

Дополнительные примеры и разбор порядка сравнения есть в официальном руководстве Sorting Techniques.

Частые вопросы

Ответы на вопросы, которые возникают при первом знакомстве с сортировкой списков.

Почему print(lst.sort()) выводит None?

Метод меняет список на месте и ничего не возвращает. Сначала вызовите lst.sort(), затем отдельно print(lst), либо выведите sorted(lst).

Можно ли отсортировать кортеж или строку методом sort()?

Нет, у неизменяемых типов этого метода нет. Функция sorted() принимает их и возвращает список, а строку обратно можно собрать через ''.join(sorted(s)).

Как отсортировать список по убыванию без reverse?

Для чисел подойдет ключ key=lambda x: -x. Но reverse=True короче, понятнее и работает с любыми типами, включая строки.

Сохраняется ли порядок одинаковых элементов?

Да, сортировка в Python стабильная, в том числе при reverse=True. Элементы с равными ключами остаются в той же последовательности, в какой были до вызова.

Что быстрее, sort() или sorted()?

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