Перейти к содержимому

??? Сортировка в Python-3 ( sorted(); .sort() )





URL источник

Разобраться с сортировкой и заполнить эту статью.

Примечание. Самая простая разница между sort()и sorted()заключается в следующем: sort()изменяет список напрямую и не возвращает никакого значения, а sorted()не изменяет список, но возвращает отсортированный список.

другими словами

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

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

  • reverse — Если True, отсортированный список перевернут (или отсортирован в порядке убывания)
  • key — функция, которая служит ключом для сравнения сортировок
https://docs.python.org/3/howto/sorting.html

https://www.programiz.com/python-programming/methods/list/sort

https://tproger.ru/translations/python-sorting/

Пример № 1

# random list
random = [(2, 2), (3, 4), (4, 1), (1, 3)]


# sort list with key
random.sort()

# print list
print('Sorted list:', random) # Sorted list: [(1, 3), (2, 2), (3, 4), (4, 1)]

Результат вывода:

Sorted list: [(1, 3), (2, 2), (3, 4), (4, 1)]

Пример № 2

# random list
random = [(2, 2), (3, 4), (4, 1), (1, 3)]

# take second element for sort
def takeSecond(elem):
    return elem[1]


# sort list with key
random.sort(key=takeSecond)

# print list
print('Sorted list:', random) # Sorted list: [(4, 1), (2, 2), (1, 3), (3, 4)]

Результат вывода:

Sorted list: [(4, 1), (2, 2), (1, 3), (3, 4)]

В Примере №2 ключу «key» присваиваем ссылку на функцию «takeSecond».

При выполнении строки «random.sort(key=takeSecond)» каждый элемент из списка [(2, 2), (3, 4), (4, 1), (1, 3)] передается в качестве аргумента функции, т.е.

(2, 2)
(3, 4)
(4, 1)
(1, 3)

Функция возвращает 2 элемент «return elem[1]«, т.е. «2, 4, 1, 3» и по этому значению производиться сортировка.

Пример № 3

Сортировка словаря по одному из ключей,

Сортировка списков по ключу.
У списков есть метод sort(), который сортирует элементы. Также есть аргумент reverse, с помощью которого можно отсортировать в обратном порядке при значении True.
Но еще есть аргумент key, отвечающий за критерий сортировки. Он принимает функцию, которая применяется к каждому элементу. Возвращаемый результат и есть критерий, по которому произойдет сортировка.

В примере ниже у нас есть список из словарей, которые содержать описания машин. Мы отсортировали список по годам их выпуска, то есть по ключу ‘year’.

использую lambda (анонимные функция)

cars = [
    {'brand1': 'Ford', 'year': 2005},
    {'brand': 'Mitsubishi', 'year': 2000},
    {'brand': 'BMW', 'year': 2019},
    {'brand': 'VW', 'year': 2011}
]

print('Было\n', cars, '\n')
cars.sort(key = lambda car: car['year'])

print('Стало\n', cars)

или использую Функцию

cars = [
    {'brand1': 'Ford', 'year': 2005},
    {'brand': 'Mitsubishi', 'year': 2000},
    {'brand': 'BMW', 'year': 2019},
    {'brand': 'VW', 'year': 2011}
]

def function_jp(car):
    return car['year']

print('Было\n', cars, '\n')
cars.sort(key = function_jp)

print('Стало\n', cars)

Результат вывода:

Было

 [{'brand1': 'Ford', 'year': 2005}, {'brand': 'Mitsubishi', 'year': 2000}, {'brand': 'BMW', 'year': 2019}, {'brand': 'VW', 'year': 2011}] 

Стало

 [{'brand': 'Mitsubishi', 'year': 2000}, {'brand1': 'Ford', 'year': 2005}, {'brand': 'VW', 'year': 2011}, {'brand': 'BMW', 'year': 2019}]

Пример № 4

# sorting using custom key
employees = [
    {'Name': 'Alan Turing', 'age': 25, 'salary': 10000},
    {'Name': 'Sharon Lin', 'age': 30, 'salary': 8000},
    {'Name': 'John Hopkins', 'age': 18, 'salary': 1000},
    {'Name': 'Mikhail Tal', 'age': 40, 'salary': 15000},
]


def print_jp(dict_jp):
    # Вывод построчно передаваемого списка
    for s in dict_jp:
        print(s)
    print('\n\n')

# настраиваемые функции для получения информации о сотрудниках
def get_name(employee):
    # Будем сортировать по ключую 'Name'
    return employee['Name'] # return employee.get('Name') # Аналог


def get_age(employee):
    # Будем сортировать по ключую 'age'
    return employee['age'] # return employee.get('age') # Аналог


def get_salary(employee):
    # Будем сортировать по ключую 'salary'
    return employee['salary']# return employee.get('') # Аналог


# sort by name (Ascending order)
employees.sort(key=get_name)
print_jp(employees)

# sort by Age (Ascending order)
employees.sort(key=get_age)
print_jp(employees)

# sort by salary (Descending order)
employees.sort(key=get_salary, reverse=True)
print_jp(employees)

Результат вывода:

{'Name': 'Alan Turing', 'age': 25, 'salary': 10000}
{'Name': 'John Hopkins', 'age': 18, 'salary': 1000}
{'Name': 'Mikhail Tal', 'age': 40, 'salary': 15000}
{'Name': 'Sharon Lin', 'age': 30, 'salary': 8000}


{'Name': 'John Hopkins', 'age': 18, 'salary': 1000}
{'Name': 'Alan Turing', 'age': 25, 'salary': 10000}
{'Name': 'Sharon Lin', 'age': 30, 'salary': 8000}
{'Name': 'Mikhail Tal', 'age': 40, 'salary': 15000}


{'Name': 'Mikhail Tal', 'age': 40, 'salary': 15000}
{'Name': 'Alan Turing', 'age': 25, 'salary': 10000}
{'Name': 'Sharon Lin', 'age': 30, 'salary': 8000}
{'Name': 'John Hopkins', 'age': 18, 'salary': 1000}

Пример № 5

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

Python предоставляет удобные функции, упрощающие и ускоряющие реализацию сортировки.

Модуль  operator имеет itemgetter()attrgetter()и methodcaller()функцию.

Используя эти функции, приведенные выше примеры становятся проще и быстрее:

student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
    ]


from operator import itemgetter, attrgetter

print( sorted(student_tuples, key=itemgetter(1, 2)) )

Результат вывода: сперва сортируется по 2-у аргументу, а уже потом по 3-му аргументу.

[(‘john’, ‘A‘, 15), (‘dave’, ‘B‘, 10), (‘jane’, ‘B‘, 12)]

from operator import itemgetter, attrgetter

class Student:
    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age

    def __repr__(self):
        return repr((self.name, self.grade, self.age))



student_objects = [
    Student('john', 'A', 15),
    Student('jane', 'B', 12),
    Student('dave', 'B', 10)
    ]



print( sorted(student_objects, key=attrgetter('grade', 'age')) )

Результат вывода:

[(‘john’, ‘A‘, 15), (‘dave’, ‘B‘, 10), (‘jane’, ‘B‘, 12)]

Пример № 6

для реверса сортировки в обратном порядке используется параметр

, reverse=True
но поскольку его можно применить стазу ко всем выбранным ключам сортировки
print( sorted(student_objects, key=attrgetter('grade', 'age')), reverse = True) )
print( sorted(student_tuples, key=itemgetter(1, 2), reverse = True) )
, то чтобы можно было указать нужен ли реверс для конкретного ключа стоит сделать так:
from operator import itemgetter, attrgetter

class Student:
    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age

    def __repr__(self):
        return repr((self.name, self.grade, self.age))


student_objects = [
    Student('john', 'A', 15),
    Student('jane', 'B', 12),
    Student('dave', 'B', 10)
    ]


def multisort(xs, specs):
    for key, reverse in reversed(specs):
        xs.sort(key=attrgetter(key), reverse=reverse)
    return xs

print(  multisort(list(student_objects), (('grade', True), ('age', False))) )

((‘grade’, True), (‘age’, False)) в программе выше задана такая сортировка, т.е. для ключа ‘grade’ используем реверс (т.е. сортируем в обратном направлении), а для ключа ‘age’ реверс не используем.

Результат вывода:

[(‘dave’, ‘B’, 10), (‘jane’, ‘B’, 12), (‘john’, ‘A’, 15)]

Добавить комментарий