Функция sorted()
возвращает новый отсортированный список итерируемого объекта (списка, словаря, кортежа). По умолчанию она сортирует его по возрастанию.
Сортировка строк осуществляется по ASCII-значениям.
- Возвращаемое значение —
List
(список). - Синтаксис:
sorted(iterable,key=None,reverse=False)
. iterable
: строка, список, кортеж, множество, словарьkey
(необязательный параметр): если указать ключ, то сортировка будет выполнена по функции этого ключа.reverse
(необязательный параметр): по умолчанию сортировка выполняется по возрастанию. Если указатьreverse=True
, то можно отсортировать по убыванию.
# Сортировка строки
s2="hello"
print(sorted(s2)) # Вывод:['e', 'h', 'l', 'l', 'o']
print(sorted(s2, reverse=True)) # Вывод:['o', 'l', 'l', 'h', 'e']
# Сортировка списка
l1=[1, 4, 5, 2, 456, 12]
print(sorted(l1)) # Вывод:[1, 2, 4, 5, 12, 456]
print(sorted(l1, reverse=True)) # Вывод:[456, 12, 5, 4, 2, 1]
# Сортировка кортежа
t1=(15, 3, 5, 7, 9, 11, 42)
print(sorted(t1)) # Вывод:[3, 5, 7, 9, 11, 15, 42]
print(sorted(t1, reverse=True)) # Вывод:[42, 15, 11, 9, 7, 5, 3]
# Сортировка списка кортежей
t2=[(1, 2), (11, 12), (0, 2), (3, 2)]
print(sorted(t2)) # Вывод:[(0, 2), (1, 2), (3, 2), (11, 12)]
print(sorted(t2, reverse=True)) # Вывод:[(11, 12), (3, 2), (1, 2), (0, 2)]
# Сортировка множества
s1={1, 4, 3, 6, 2, 8, 11, 32}
print(sorted(s1)) # Вывод:[1, 2, 3, 4, 6, 8, 11, 32]
print(sorted(s1, reverse=True)) # Вывод:[32, 11, 8, 6, 4, 3, 2, 1]
# Сортировка словаря
d1={2: 'red', 1: 'green', 3: 'blue'}
# Вернется список отсортированных ключей
print(sorted(d1)) # Вывод:[1, 2, 3]
# Вернется список отсортированных значений
print(sorted(d1.values())) # Вывод:['blue', 'green', 'red']
# Вернется список кортежей (ключ, значение), отсортированный по ключам.
print(sorted(d1.items())) # Вывод:[(1, 'green'), (2, 'red'), (3, 'blue')]
# Сортировка словаря в обратном порядке
print(sorted(d1, reverse=True)) # Вывод:[3, 2, 1]
print(sorted(d1.values(), reverse=True)) # Вывод:['red', 'green', 'blue']
print(sorted(d1.items(), reverse=True)) # Вывод:[(3, 'blue'), (2, 'red'), (1, 'green')]
Параметр key
Итерируемый объект можно также отсортировать по функции, указанной в параметре key
. Это может быть:
- Встроенная функция,
- Определенная пользователем функция,
- Лямбда-функция,
- itemgetter,
- attrgetter.
1. Встроенная функция
len()
— посчитает длину объекта. Если указать len
в виде параметра key, то сортировка будет выполнена по длине.
# Сортировка словаря на основе функции len
l1 = {'carrot': 'vegetable', 'red': 'color', 'apple': 'fruit'}
# Возвращает список ключей, отсортированных по функции len
print(sorted(l1, key=len))
# Вывод: ['red', 'apple', 'carrot']
# Возвращает список значений, отсортированных на основе функции len
print(sorted(l1.values(), key=len))
# Вывод: ['fruit', 'color', 'vegetable']
# Сортировка списка на основе функции len
l1 = ['blue', 'green', 'red', 'orange']
print(sorted(l1, key=len))
# Вывод: ['red', 'blue', 'green', 'orange']
abs()
вернет абсолютно значение числа. Если задать abs
для key
, то сортировка будет основана на абсолютном значении.
# Сортировка списка по абсолютному значению
l1 = [1, -4, 5, -7, 9, 2]
print(sorted(l1, key=abs))
# Вывод: [1, 2, -4, 5, -7, 9]
str.lower()
— конвертирует все символы в верхнем регистре в нижний регистр. В таком случае список будет отсортирован так, будто бы все символы в нижнем регистре.
s1 = "Hello How are you"
# Разбивает строку и сортирует по словам
print(sorted(s1.split()))
# Вывод: ['Hello', 'How', 'are', 'you']
# Разбивает строку и сортирует после применения str.lower ко всем элементам
print(sorted(s1.split(), key=str.lower))
# Вывод: ['are', 'Hello', 'How', 'you']
d1 = {'apple': 1, 'Banana': 2, 'Pears': 3}
# Возвращает список ключей, отсортированный по значениям
print(sorted(d1))
# Вывод: ['Banana', 'Pears', 'apple']
# Возвращает список ключей, отсортированный после применения str.lower ко всем элементам
print(sorted(d1, key=str.lower))
# Вывод: ['apple', 'Banana', 'Pears']
2. Пользовательские функции
Также можно указывать свои функции.
Пример №1: по умолчанию сортировка кортежа происходит по первому элементу в нем. Добавим функцию, которая будет возвращать второй элемент кортежа. Теперь и сортировка будет опираться на соответствующий элемент.
# напишем функцию для получения второго элемента
def sort_key(e):
return e[1]
l1 = [(1, 2, 3), (2, 1, 3), (11, 4, 2), (9, 1, 3)]
# По умолчанию сортировка выполняется по первому элементу
print(sorted(l1))
# Вывод: [(1, 2, 3), (2, 1, 3), (9, 1, 3), (11, 4, 2)]
# Сортировка по второму элементу с помощью функции sort_key
print(sorted(l1, key=sort_key))
# Вывод: [(2, 1, 3), (9, 1, 3), (1, 2, 3), (11, 4, 2)]
Пример №2: можно сортировать объекты класса с помощью функций. Вот как это происходит:
- У класса
Studen
есть три атрибута:name
,rollno
,grade
. - Создаются три объекта этого класса:
s1
,s2
,s3
. - Создается список
s4
, который содержит все три объекта. - Дальше происходит сортировка по этому списку.
- Определенная функция (
sort_key
) возвращает атрибутrollno
. - В функции sorted эта функция задана для параметра
key
. - Теперь
sorted()
возвращает список объектовStudent
, которые отсортированы по значениюrollno
.
class Student:
def __init__(self, name, rollno, grade):
self.name = name
self.rollno = rollno
self.grade = grade
def __repr__(self):
return f"{self.name}-{self.rollno}-{self.grade}"
# Создание объектов
s1 = Student("Paul", 15, "second")
s2 = Student("Alex", 12, "fifth")
s3 = Student("Eva", 21, "first")
s4 = [s1, s2, s3]
# Сортировка списка объектов
# Создание функции, которая вернет rollno объекта
def sort_key(s):
return s.rollno
# сортировка списка объектов без ключевого параметра, вызывает TypeError
print(sorted(s4))
# Вывод: TypeError: '>' not supported between instances of 'Student' and 'Student'
# Сортировка списка объектов по атрибуту: rollno
s5 = sorted(s4, key=sort_key)
print(s5)
# Вывод: [Alex-12-fifth, Paul-15-second, Eva-21-first]
3. Лямбда-функция
Также в качестве ключа можно задать лямбда-функцию. Сортировка будет выполняться по ней.
Пример №1: сортировка списка объектов класса на основе лямбда-функции, переданной для параметра key
.
class Student:
def __init__(self, name, rollno, grade):
self.name = name
self.rollno = rollno
self.grade = grade
def __repr__(self):
return f"{self.name}-{self.rollno}-{self.grade}"
# Создание объектов
s1 = Student("Paul", 15, "second")
s2 = Student("Alex", 12, "fifth")
s3 = Student("Eva", 21, "first")
s4 = [s1, s2, s3]
# Сортировка списка объектов
# Создание lambda-функции, которая вернет rollno объекта
s5 = sorted(s4, key=lambda x: x.rollno)
print(s5)
# Вывод: [Alex-12-fifth, Paul-15-second, Eva-21-first]
Пример №2: сортировка кортежей по второму элементу. Лямбда-функция просто возвращает его для каждого переданного объекта.
l1 = [( 1, 2, 3), (3, 1, 1), (8, 5, 3), (3, 4, 2)]
# Сортировка по второму элементу в кортеже.
# Lambda-функция возвращает второй элемент в кортеже.
print(sorted(l1, key=lambda x: x[1]))
# Вывод: [(3, 1, 1), (1, 2, 3), (3, 4, 2), (8, 5, 3)]
4. itemgetter
operator
— это встроенный модуль, включающий много операторов. itemgetter(n)
создает функцию, которая принимает итерируемый объект (список, кортеж, множество) и возвращает n-элемент из него.
Пример №1: сортировка списка кортежей по третьему элементу в каждом из них. itemgetter()
возвращает функцию, которая получает третий элемент в кортеже. По умолчанию если key
не указать, то сортировка будет выполнена по первому элементу кортежа.
from operator import itemgetter
l1 = [(1, 2, 3), (3, 1, 1), (8, 5, 3), (3, 4, 2)]
# Сортировка по третьему элементу в кортеже
print(sorted(l1, key=itemgetter(2)))
# Вывод: [(3, 1, 1), (1, 2, 3), (3, 4, 2), (8, 5, 3)]
Пример №2: сортировка списка словарей по ключу age
.
from operator import itemgetter
# Создание списка словарей
d1 = [{'name': 'Paul', 'age': 30},
{'name': 'Alex', 'age': 7},
{'name': 'Eva', 'age': 3}]
# Сортировка по key(age) в словаре
print(sorted(d1, key=itemgetter('age')))
# Вывод: [{'name': 'Eva', 'age': 3}, {'name': 'Alex', 'age': 7}, {'name': 'Paul', 'age': 30}]
Пример №3: сортировка значений словаря с помощью itemgetter
.
from operator import itemgetter
d = {'a': [1, 2, 3], 'b': [3, 4, 5], 'c': [1, 1, 2]}
print(sorted(d.values(), key=itemgetter(1)))
# Вывод: [[1, 1, 2], [1, 2, 3], [3, 4, 5]]
5. attrgetter
operator.attrgetter(attr)
operator.attrgetter(*attrs)
Возвращает вызываемый объект, который получает attr
операнда. Если требуется больше одного аргумента, то возвращается кортеж атрибутов. Названия также могут включать троеточия.
Пример: сортировка списка объекта классов с помощью attrgetter
. Функция attrgetter
может получить атрибут объекта, а функция sorted
будет выполнять сортировку на основе этого атрибута.
from operator import attrgetter
class Student:
def __init__(self, name, rollno, grade):
self.name = name
self.rollno = rollno
self.grade = grade
def __repr__(self):
return f"{self.name}-{self.rollno}-{self.grade}"
# Создание объектов
s1 = Student("Paul", 15, "second")
s2 = Student("Alex", 12, "fifth")
s3 = Student("Eva", 21, "first")
s4 = [s1, s2, s3]
# Сортировка списка объектов по атрибуту: rollno
s5 = sorted(s4, key=attrgetter('rollno'))
print(s5)
# Вывод: [Alex-12-fifth, Paul-15-second, Eva-21-first]
Многоуровневая сортировка
- С помощью
itemgetter
можно также выполнять сортировку на нескольких уровнях.
В следующем примере сортировка значений словаря будет выполнена по второму элементу. Если же некоторые из них будут равны, то сортировка пройдет по третьему элементу.
from operator import itemgetter
d = {'a': [1, 2, 9], 'b': [3, 2, 5], 'c': [1, 1, 2]}
# Сортировка по второму, затем по третьему элементу
print(sorted(d.values(), key=itemgetter(1, 2)))
# Вывод: [[1, 1, 2], [3, 2, 5], [1, 2, 9]]
- Многоуровневая сортировка с помощью лямбда-функции в
key
.
А в этом примере сортировка кортежа будет проходить по второму элементу. В случае равенства используется третий.
l1 = [(1, 2, 3), (4, 2, 0), (2, 1, 7)]
# Сортировка по второму элементу
# Если второй элемент равен, сортировка по третьему элементу.
print(sorted(l1, key=lambda x: x[1:3]))
Сортировка смешанных типов данных
Функция sorted
не поддерживает смешанные типы данных. При попытке выполнить сортировку она вернет ошибку TypeError.
# список, содержащий смешанные типы данных
l1 = [1, 'a', 2]
print(sorted(l1))
# Вывод: TypeError: '>' not supported between instances of 'str' and 'int'
Выводы
- При сортировке списка объектов класса параметр
key
является обязательным. Если его не указать, то вернется ошибка TypeError. - Для сортировки списка объектов класса можно использовать в качестве параметра
key
определенную пользователем функцию, лямбда-функцию илиattrgetter
. - Функция
sorted()
возвращает список. - Метода
sort
отсортирует сам оригинальный список. Но функцияsorted
возвращает новый список, не изменяя оригинальный. - Метод
sort
используется только для сортировки списка. Его нельзя использовать для строки, кортежа или словаря.