Основы сортировки данных с помощью sorted() в Python

Раздел: Основы Python -> Сортировка

Основы сортировки с помощью sorted()

Основное решение:

Функция sorted() возвращает новый отсортированный список из любого итерируемого объекта. Синтаксис: sorted(iterable, key=None, reverse=False). По умолчанию сортировка выполняется по возрастанию, используя естественный порядок элементов.

numbers = [3, 1, 4, 1, 5, 9]
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # [1, 1, 3, 4, 5, 9]

Python sort lambda (сортировка с lambda в python)

[1, 1, 3, 4, 5, 9]

Python сортировка по значению (сортировка по значению в python)

Этот подход работает для любых типов, поддерживающих сравнение (числа, строки, кортежи).

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

Используйте параметр reverse=True.

sorted_numbers_desc = sorted(numbers, reverse=True)
print(sorted_numbers_desc)  # [9, 5, 4, 3, 1, 1]

Sorted values python (сортировка значений в python (sorted))

[9, 5, 4, 3, 1, 1]

Python числа в порядке возрастания (сортировка чисел по возрастанию в python)

Типичная ошибка:

Забывают, что reverse меняет только порядок, но не влияет на ключ сортировки.

Как отсортировать строки без учёта регистра?

Параметр key позволяет задать функцию преобразования элемента перед сравнением. Для строк удобно использовать str.lower.

words = ['Apple', 'banana', 'Cherry', 'date']
sorted_words = sorted(words, key=str.lower)
print(sorted_words)  # ['Apple', 'banana', 'Cherry', 'date']
['Apple', 'banana', 'Cherry', 'date']

Проблема:

Без key=str.lower заглавные буквы окажутся перед строчными из‑за кодов ASCII: ['Apple', 'Cherry', 'banana', 'date'].

Как отсортировать список словарей по определённому ключу?

Используйте лямбда-функцию или operator.itemgetter.

students = [{'name': 'Alex', 'grade': 85}, {'name': 'Zoe', 'grade': 92}, {'name': 'Bob', 'grade': 78}]
sorted_students = sorted(students, key=lambda s: s['grade'])
print(sorted_students)
[{'name': 'Bob', 'grade': 78}, {'name': 'Alex', 'grade': 85}, {'name': 'Zoe', 'grade': 92}]

Ошибка:

Если ключ в словаре отсутствует, возникнет KeyError. Решение - использовать dict.get с значением по умолчанию: key=lambda s: s.get('grade', 0).

Как отсортировать список объектов по атрибуту?

Применяется operator.attrgetter или лямбда.

from operator import attrgetter

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __repr__(self):
        return f'{self.name}({self.age})'

people = [Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)]
sorted_people = sorted(people, key=attrgetter('age'))
print(sorted_people)  # [Bob(25), Alice(30), Charlie(35)]
[Bob(25), Alice(30), Charlie(35)]

Проблема:

Если атрибут не существует, возникает AttributeError. Проверяйте наличие атрибута или используйте getattr(obj, attr, default).

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

Передайте в key кортеж из полей. Сортировка выполняется последовательно.

data = [('apple', 2), ('banana', 1), ('cherry', 2), ('apple', 1)]
sorted_data = sorted(data, key=lambda x: (x[0], x[1]))
print(sorted_data)  # [('apple', 1), ('apple', 2), ('banana', 1), ('cherry', 2)]
[('apple', 1), ('apple', 2), ('banana', 1), ('cherry', 2)]

Нюанс:

Порядок полей в кортеже определяет приоритет. Для убывания по одному из полей можно использовать отрицательное значение (для чисел) или reverse с несколькими проходами.

Как выполнить сортировку с пользовательской функцией сравнения (например, для сложных правил)?

Используйте functools.cmp_to_key для преобразования старой функции сравнения в key. Но для новых проектов предпочтительнее key.

from functools import cmp_to_key

def compare(x, y):
    if x % 2 == y % 2:
        return -1 if x < y else 1
    return -1 if x % 2 == 0 else 1  # чётные раньше нечётных

numbers = [3, 1, 4, 6, 5]
sorted_custom = sorted(numbers, key=cmp_to_key(compare))
print(sorted_custom)  # [4, 6, 1, 3, 5]
[4, 6, 1, 3, 5]

Предостережение:

Использование cmp_to_key медленнее, чем key, и не рекомендуется для больших данных.

Цели и случаи использования:

  • sorted() применяется для создания нового отсортированного представления данных без изменения исходного объекта.
  • Сортировка с ключом - основной инструмент для кастомизации порядка (сортировка строк без учёта регистра, сортировка словарей или объектов).
  • Сортировка по нескольким критериям часто нужна при анализе данных (таблицы, логи).
  • Устойчивость сортировки важна, когда требуется сохранить исходный порядок для равных элементов (например, при первичной сортировке по дате, затем по приоритету).

Расширенные примеры использования sorted()

Пример 1. Сортировка списка кортежей по второму элементу (по убыванию)

Пример
pairs = [(1, 5), (3, 2), (2, 8), (4, 1)]
sorted_pairs = sorted(pairs, key=lambda x: x[1], reverse=True)
print(sorted_pairs)
[(2, 8), (1, 5), (3, 2), (4, 1)]

Пример 2. Сортировка строк по длине (сначала короткие, потом длинные)

Пример
words = ['python', 'java', 'c', 'rust', 'javascript']
sorted_by_len = sorted(words, key=len)
print(sorted_by_len)
['c', 'java', 'rust', 'python', 'javascript']

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

Пример 3. Сортировка словаря по значениям (с получением отсортированного списка ключей)

Пример
scores = {'Alice': 88, 'Bob': 95, 'Charlie': 70, 'Diana': 92}
sorted_names = sorted(scores, key=lambda name: scores[name], reverse=True)
print(sorted_names)  # ['Bob', 'Diana', 'Alice', 'Charlie']
['Bob', 'Diana', 'Alice', 'Charlie']

Пример 4. Сортировка с преобразованием типов (например, строки в числа)

Пример
data = ['10', '2', '1', '22']
# без key будет лексикографический порядок ['1', '10', '2', '22']
sorted_numeric = sorted(data, key=int)
print(sorted_numeric)  # ['1', '2', '10', '22']
['1', '2', '10', '22']

Ошибка:

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

Пример 5. Сортировка списка списков по первому и второму столбцу

Пример
matrix = [[3, 1], [1, 4], [3, 2], [1, 1]]
sorted_matrix = sorted(matrix, key=lambda row: (row[0], row[1]))
print(sorted_matrix)
[[1, 1], [1, 4], [3, 1], [3, 2]]

Пример 6. Сортировка с использованием operator.itemgetter для ускорения

Пример
from operator import itemgetter

records = [('A', 3), ('B', 1), ('C', 2)]
sorted_records = sorted(records, key=itemgetter(1))
print(sorted_records)  # [('B', 1), ('C', 2), ('A', 3)]
[('B', 1), ('C', 2), ('A', 3)]

Пример 7. Сортировка дат из строк (формат ISO)

Пример
dates = ['2023-05-10', '2022-11-15', '2023-01-20', '2022-12-05']
sorted_dates = sorted(dates, key=lambda d: (int(d[0:4]), int(d[5:7]), int(d[8:10])))
print(sorted_dates)
['2022-11-15', '2022-12-05', '2023-01-20', '2023-05-10']

Для реальных проектов лучше использовать datetime.datetime.strptime в качестве ключа.

Пример 8. Неустойчивая сортировка с помощью list.sort() – для сравнения

Пример
original = [('A', 2), ('B', 1), ('C', 2)]
original.sort(key=lambda x: x[1])  # модифицирует оригинал
print(original)  # [('B', 1), ('A', 2), ('C', 2)]
[('B', 1), ('A', 2), ('C', 2)]

Порядок ('A',2) и ('C',2) сохранён (устойчивость).

Пример 9. Сортировка по убыванию с несколькими критериями – комбинирование через отрицание

Пример
data = [('apple', 2), ('banana', 1), ('cherry', 2), ('apple', 1)]
sorted_mixed = sorted(data, key=lambda x: (x[0], -x[1]))  # имя по возр., количество по убыв.
print(sorted_mixed)
[('apple', 2), ('apple', 1), ('banana', 1), ('cherry', 2)]

Пример 10. Сортировка с учётом локали (для букв с диакритиками)

Пример
import locale
locale.setlocale(locale.LC_ALL, 'ru_RU.UTF-8')  # для русской локали

words = ['ёлка', 'ель', 'ёж', 'еда']
sorted_locale = sorted(words, key=locale.strxfrm)
print(sorted_locale)  # ['еда', 'ель', 'ёж', 'ёлка'] (правильный порядок для русского языка)
['еда', 'ель', 'ёж', 'ёлка']

Проблема:

Для работы locale требуется установленная системная локаль. В некоторых средах (например, Docker) может отсутствовать.

Сортировка значений в Python (sorted) - comments

En
Sorted values python (python)