Упорядочивание списков и массивов в Python: практические примеры

Раздел: Python -> Работа со списками и массивами

Сортировка элементов в Python

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

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

Наиболее эффективный способ – использовать встроенную сортировку с параметрами key и reverse.


nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sort()  # сортировка на месте
print(nums)  # [1, 1, 2, 3, 4, 5, 6, 9]

words = ['banana', 'apple', 'cherry']
sorted_words = sorted(words, reverse=True)
print(sorted_words)  # ['cherry', 'banana', 'apple']
    

вставить элемент python (вставка элемента в список python)

Параметр key задаёт функцию, вычисляющую значение для каждого элемента, по которому происходит сравнение. Например, сортировка строк по длине:


words = ['python', 'java', 'c', 'rust']
words.sort(key=len)
print(words)  # ['c', 'java', 'rust', 'python']
    

Python несколько элементов списка (выбор нескольких элементов из списка python)

Типичная ошибка: попытка сортировки списка с элементами разных типов, например чисел и строк. Python 3 не поддерживает сравнение int и str – возникает TypeError. Решение: привести все элементы к одному типу или использовать key, возвращающий совместимые значения.

Как отсортировать список кортежей по второму элементу?

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


data = [(1, 'apple'), (2, 'banana'), (3, 'cherry')]
data.sort(key=lambda x: x[1])
print(data)  # [(1, 'apple'), (2, 'banana'), (3, 'cherry')]
    

выведите все элементы python (вывод всех элементов списка в python)

Примечание: кортежи сравниваются поэлементно, поэтому если первые элементы равны, сравнение переходит ко вторым.

Проблема: если ключ возвращает None (например, функция, возвращающая None), возникает TypeError. Убедитесь, что функция key всегда возвращает значение, поддерживающее сравнение.

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

Функция key должна извлекать значение по ключу.


users = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob', 'age': 25},
    {'name': 'Charlie', 'age': 35}
]
sorted_users = sorted(users, key=lambda user: user['age'])
print(sorted_users)
# [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
    

вывести элемент массива python (вывод элемента массива в python)

Для сортировки по нескольким полям используется кортеж ключей:


sorted_users = sorted(users, key=lambda u: (u['age'], u['name']))
    

Python максимальный элемент списка (максимальный элемент списка в python)

Ошибка: если у части словарей отсутствует ключ, возникнет KeyError. Решение: использовать dict.get() с значением по умолчанию.

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

Можно задать атрибут через лямбду или operator.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)]
people.sort(key=lambda p: p.age)
print(people)  # [Bob(25), Alice(30), Charlie(35)]
    

Python каждый элемент списка (обработка каждого элемента списка в python)

Если нужно определить естественный порядок для объектов, реализуют методы __lt__, __gt__ и т.д., после чего объекты можно сортировать без ключа.

Проблема: без определения __lt__ (или __gt__ вместе с functools.total_ordering) сравнение объектов не поддерживается, возникает TypeError. Рекомендуется использовать key.

Как использовать собственную функцию сравнения для сортировки?

В Python 3 нет аргумента cmp, но можно преобразовать сравнивающую функцию в ключ через functools.cmp_to_key.


from functools import cmp_to_key

def cmp_len_reverse(a, b):
    if len(a) < len(b):
        return 1
    elif len(a) > len(b):
        return -1
    else:
        return 0

words = ['python', 'java', 'c', 'rust']
sorted_words = sorted(words, key=cmp_to_key(cmp_len_reverse))
print(sorted_words)  # ['python', 'rust', 'java', 'c']
    

Python первый элемент массива (первый элемент массива в python)

Этот подход менее производителен, чем key, и рекомендуется только для сложной логики сравнения.

Ошибка: функция сравнения должна возвращать именно -1, 0, 1, иначе поведение не определено.

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

Функции operator.itemgetter и operator.attrgetter создают эффективные вызываемые объекты для доступа по индексу / ключу или атрибуту.


from operator import itemgetter, attrgetter

data = [(1, 'z'), (2, 'a'), (3, 'm')]
data.sort(key=itemgetter(1))
print(data)  # [(2, 'a'), (3, 'm'), (1, 'z')]

# Для объектов
people.sort(key=attrgetter('age'))
print(people)  # [Bob(25), Alice(30), Charlie(35)]
    

перебор элементов списка в python (перебор элементов списка в python)

Метод itemgetter также поддерживает множественные индексы для сортировки по нескольким полям.

Замечание: использование itemgetter немного быстрее лямбды, но разница заметна только на больших данных.

Как отсортировать по одному полю по возрастанию, а по другому по убыванию?

Для числовых полей можно изменить знак в ключе.


data = [('a', 10), ('b', 5), ('a', 5)]
sorted_data = sorted(data, key=lambda x: (x[0], -x[1]))
print(sorted_data)  # [('a', 10), ('a', 5), ('b', 5)]
    

как посчитать элементы в списке python (подсчет элементов в списке python)

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


# Стабильная сортировка: сначала по вторичному ключу (убывание),
# потом по первичному (возрастание)
data.sort(key=lambda x: x[1], reverse=True)
data.sort(key=lambda x: x[0])
print(data)  # [('a', 10), ('a', 5), ('b', 5)]
    

Python list find (поиск в списке python)

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

Как отсортировать список, игнорируя регистр букв?

Использовать key=str.lower.


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

наибольший элемент python (поиск наибольшего элемента в python)

Этот метод создаёт новый список в нижнем регистре для сравнения, не изменяя исходные строки.

Ошибка: прямое применение str.lower к списку с числами вызовет AttributeError. Убедитесь, что все элементы – строки.

Что делать при попытке сортировки списка с разнотипными элементами?

Если типы несовместимы, возникает TypeError. Можно отсортировать, преобразовав все элементы к строке, или отфильтровать по типу, или определить пользовательский ключ.


mixed = [42, 'hello', 1, 'world', 5]
mixed.sort(key=str)
print(mixed)  # [1, 42, 5, 'hello', 'world']
    

Python find first (поиск первого элемента в python)

Преобразование в строку допустимо, если порядок строкового представления устраивает. В противном случае требуется более сложная логика.

Проблема: сравнение строковых представлений чисел и строк может дать неожиданный порядок (например, '10' < '2'). Для чисел с разной разрядностью лучше приводить к числовому типу.

Как отсортировать список в обратном порядке с сохранением ключа?

Параметр reverse=True можно комбинировать с key.


words = ['python', 'java', 'c', 'rust']
words.sort(key=len, reverse=True)
print(words)  # ['python', 'rust', 'java', 'c']
    

Это сортирует сначала по длине в убывающем порядке. Важно: reverse применяется после сравнения через key.

Ошибка: путать порядок применения – reverse не инвертирует ключ, а инвертирует результат сравнения.

Дополнительно: для частичной сортировки (топ N элементов) можно использовать heapq.nlargest и heapq.nsmallest, которые не сортируют весь список.

Общая рекомендация: для большинства задач достаточно sorted() или list.sort() с key. Избегайте самописных алгоритмов сортировки – встроенный Timsort оптимизирован по скорости и памяти.

- следующий элемент массива python (получение следующего элемента массива в python)
- Python уникальные элементы (получение уникальных элементов в python)
- проверить элемент списка python (проверка наличия элемента в списке python)

Расширенные примеры сортировки в Python

Сортировка с пользовательским компаратором для сложной логики

Пример: отсортировать числа так, чтобы сначала шли чётные по возрастанию, затем нечётные по возрастанию.

Пример

from functools import cmp_to_key

def special_cmp(a, b):
    # сначала сравниваем чётность (чётные меньше)
    if a % 2 != b % 2:
        return -1 if a % 2 == 0 else 1
    # внутри одной группы по возрастанию
    return -1 if a < b else (1 if a > b else 0)

nums = [5, 2, 7, 1, 8, 3, 4]
result = sorted(nums, key=cmp_to_key(special_cmp))
print(result)  # [2, 4, 8, 1, 3, 5, 7]
[2, 4, 8, 1, 3, 5, 7]

Сортировка списка списков по сумме элементов

Пусть дан список подсписков. Нужно отсортировать их по убыванию суммы.

Пример

matrix = [[1, 2, 3], [10, 20], [5, 5, 5, 5]]
matrix.sort(key=sum, reverse=True)
print(matrix)  # [[10, 20], [1, 2, 3], [5, 5, 5, 5]]
[[10, 20], [1, 2, 3], [5, 5, 5, 5]]

Сортировка с несколькими ключами разного направления с помощью lambda

Дан список кортежей (город, население, площадь). Отсортировать по населению по убыванию, а при равенстве – по площади по возрастанию.

Пример

cities = [
    ('Москва', 12_600_000, 2511),
    ('Санкт-Петербург', 5_400_000, 1439),
    ('Новосибирск', 1_620_000, 505),
    ('Екатеринбург', 1_500_000, 468),
]
cities.sort(key=lambda c: (-c[1], c[2]))
for city in cities:
    print(city)
('Москва', 12600000, 2511)
('Санкт-Петербург', 5400000, 1439)
('Новосибирск', 1620000, 505)
('Екатеринбург', 1500000, 468)

Сортировка с помощью operator.itemgetter для множественных ключей

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

Пример

from operator import itemgetter

# Сначала сортируем по площади (меньшая площадь выше)
cities.sort(key=itemgetter(2))
# Затем стабильная сортировка по населению по убыванию
cities.sort(key=itemgetter(1), reverse=True)

Использование functools.partial для создания ключа с параметрами

Пусть требуется сортировать строки по количеству вхождения заданного символа.

Пример

from functools import partial

def count_char(s, ch):
    return s.count(ch)

words = ['apple', 'banana', 'cherry', 'date']
words.sort(key=partial(count_char, ch='a'))
print(words)  # ['cherry', 'apple', 'date', 'banana'] (в 'cherry' нет 'a', в 'banana' 3)
['cherry', 'apple', 'date', 'banana']

Сортировка с сохранением исходного порядка для равных элементов (стабильность)

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

Пример

records = [
    ('Alice', 'HR'),
    ('Bob', 'IT'),
    ('Charlie', 'HR'),
    ('David', 'IT')
]
# Сначала по отделам (убывание)
records.sort(key=lambda r: r[1], reverse=True)
# Затем по имени (возрастание)
records.sort(key=lambda r: r[0])
print(records)
# [('Alice', 'HR'), ('Bob', 'IT'), ('Charlie', 'HR'), ('David', 'IT')]
# Порядок 'Alice' и 'Charlie' в отделе HR не изменился относительно первого прохода.
[('Alice', 'HR'), ('Bob', 'IT'), ('Charlie', 'HR'), ('David', 'IT')]

Сортировка списка с помощью heapq.nlargest для получения топ-N элементов

Если нужно только несколько наибольших элементов, частичная сортировка эффективнее.

Пример

import heapq

scores = [23, 45, 67, 12, 89, 90, 34, 56]
top3 = heapq.nlargest(3, scores)
print(top3)  # [90, 89, 67]
[90, 89, 67]

Сортировка элементов в Python - comments

En
сортировка элементов python (python)