Давайте разбираться как сортировки работают в Python. Мы будем пользоваться функцией "sorted", которая может работать со списками, кортежами, строками, множествами, даже словарями, но со словарями есть небольшие особенности, поэтому мы про них поговорим попозже, отдельно. Начнем с самого простого, отсортируем список чисел, для сортировки неважно целые они или вещественные, здесь они смешанные. Давайте представим, что это список оценок и мы хотим их напечатать по возрастания от меньшего к большему. Функция "sorted" и как аргумент передаю мой список, получили список, отсортированный по возрастанию. Обратите внимание, что мы всегда получим список, если бы даже, например, моим исходным объектом было бы множество или кортеж, функция "sorted" нам всегда вернет отсортированный список, имейте это ввиду. Нам не всегда нужно сортировать по возрастанию, иногда мы хотим, наоборот, от большего к меньшему. Давайте посмотрим, как это сделать, "print(sorted(marks))", пока все то же самое и у функции "sorted" есть именованный параметр, называется он "reverse", развернуть, и я ставлю ему значение "true", то есть отсортируй и разверни. Запускаю, и вот у меня этот второй раз, список отсортировался по убыванию, от большего к меньшего. Давайте еще раз проверим, что исходный список это функция не меняет, исходный список у нас остался тот же самый, вот он, не отсортированный. Если нам нужно продолжать работу со списком уже к которому применена сортировка, мы можем либо нашу переменную изначальную перезаписать, если нам не надо ее сохранять, либо сохранить в новую. Напечатаем. Оригинальный список, отсортированный список, который сохранили в другую переменную. Функция "sorted", как я уже сказала, работает с разными типами данных, с разными последовательностями и коллекциями, которые она может отсортировать, но кроме чисел она может отсортировать и строки, мы сейчас про это поговорим подробнее. Главное не пытайтесь отсортировать с ее помощью список из смешанного типа данных. Например, мы использовали такой список в одном из наших прошлых видео, у нас здесь имя студента, год рождения студентки, целое число, и опять строка, название программы на которой она учится. Не получилось у функции сортировки такой список отсортировать, потому что в какой-то момент ей пришлось сравнить целое число и строку, такая операция недопустима, и мы получили ошибку. Но списки чисел или множества чисел, или другие элементы и списки строк, функция "sorted" отсортировать сможет. Давайте смотреть как она работает со строками. Предположим у нас есть вот такой список фруктов. Некоторые фрукты написаны по-русски, некоторые по-английски, некоторые с маленькой буквы, некоторые с большой, это на самом деле все важно и я пытаюсь его отсортировать. Как мы видим ошибки не было, то есть строки мы действительно сортировать можем, но сортировка получилась какая-то странная. Сначала у нас идут слова на английском, но это еще ладно, вначале у нас идет слово "Orange", написанное с большой "O", заглавной, потом слово "apple", очевидно, что "apple" мы ожидали увидеть первым, а дальше у нас идет "Апельсин". Ладно, хорошо, считаем, что сначала мы отсортировали английские слова, слова написаны латиницей, теперь перешли к кириллице, "Апельсин" с большой буквы — первый, а потом идет "Яблоко", очевидно "Яблоко" должно быть последним всегда, в любом отсортированном списке, если нет какого-то другого слова, которое идет позже него по второй или третьей букве, и слово "манго" с маленькой буквы, которое если бы мы сортировали с вами как люди, мы бы явно поставили манго между апельсином и яблоком. Мы с вами обсуждали, что в таблице кодировки, символы стоят на своих строго отведенных и за ними закрепленных местах. Например, сначала идут какие-то спецсимволы, потом цифры, потом заглавные латинские буквы, потом строчные латинские буквы, потом уже для нас актуальна кириллица, бывают шрифты без кириллицы, но с греческим алфавитом, и каждая буква в этой таблице имеет свое место. Поэтому Python идет и расставляет эти слова в соответствии с этой таблицей, поэтому заглавная буква тоже влияет на то, где окажется ваше слово в отсортированном списке. Вряд ли, если бы мы решали задачу расположение слов по алфавиту, нас бы устроил такой результат. Давайте, например, приведем все слова к нижнему регистру. Мы умеем делать такие операции с помощью функции "map". Я "fruits" назову "lower", с помощью функции "map" применяю метод "str.lower", который приводит к нижнему регистру, ко всем фруктам в нашем списке. Давайте я напечатаю, что получилось сначала. Теперь прекрасный, отредактированный список. Давайте теперь попробуем его отсортировать. Такая сортировка по алфавиту, наверное, больше соответствует нашим ожиданиям, чем вот этот вариант, у нас "apple" идет первым, потом "orange", потом "апельсин", "манго", "яблоко". Мы бы, наверное, с вами сортировали точно так же. Что мы потеряли? Мы потеряли исходный список. Возможно написание слов именно с заглавной буквы — для нас было важным. Можно ли как-то сортировать список, при этом сохранив регистр? На самом деле можем. У функции "sorted", есть именованный параметр, мы говорили с вами про него, он называется "key" — ключ, он работает очень похоже на функцию "map". Я могу здесь присвоить этому параметру название какой-то функции и эта функция применится ко всем элементам моего списка перед сортировкой. Давайте посмотрим как сработает. Обратите внимание, у нас отсортировалось по алфавиту, как бы мы с вами это ожидали, как будто бы слова приведены к нижнему регистру, но регистр сам сохранен, то есть у нас слово "Orange" написано с заглавной, "Апельсин" и "Яблоко", как было в оригинальном списке, но отсортировано по алфавиту, как мы с вами это представляем. Итак, давайте разберемся, проговорим, как работает этот параметр "key". На этапе сортировки, Python получают этот список. Дальше мы говорим, а теперь примени ко всем элементам этого списка, вот эту функцию и Python, по сути создает новый список, где ко всем элементам применен метод строк, "key=str.lower", и все слова в нашем случае, записаны сточными буквами. Python запоминает какое слово из оригинального списка, соответствует какому слову или элементу из нового списка, там, где функция применена и дальше он сортирует новый список, но потом идет и смотрит, на первое место я поставил "apple", что у меня соответствовало этому слову в моем оригинальном списке? Слово "apple", я его и поставлю. На второе место в моем измененном списке я поставил слово "orange" написанное с маленькой буквы, а что ему соответствовало в моем оригинальном списке? Слово "Orange" написанное с большой буквы, и он его поставил. Таким образом, мы не изменяем исходные элементы, но используем эту функцию для того, чтобы отсортировать что-то в соответствии с нашими какими-то представлениями. Позже мы посмотрим какие более сложные функции можно сюда подставлять, например, для сортировки словаря или еще каких-то более сложных структур. Еще одна ловушка, в которую можно попасть, если у вас список из чисел-строк. В отдельные ячейки введу. Давайте представим, что у нас есть список каких-то дат. Давайте я их сразу буду переводить в список, введу их, что-нибудь у нас происходит 1 числа, что-то 10, 14, 8, 21 и 28, вот такие даты. Давайте смотреть, список строк. Иногда, например, вы считали список, там строки и вы знаете, что вы никакие арифметические действия дальше проводить не будете. Предположим, эта дата и вам надо их отсортировать и это единственное что вам с этим списком надо сделать. Вам кажется, ну какая разница для сортировки, строки или целые числа? Зачем я буду делать операцию перевода в числа? И вы решаете отсортировать его. Отсортировалось, но как-то странно, сначала идет "1", вроде бы ожидаемо, на самом деле все ожидаемо, кроме того, что "8" попала в конец. Ведь дело в том, что когда Python видит числа в строковом представлении, он не сравнивает их как числа между собой, как например, в нашем первом примере с оценками, он сравнивает их как символы. То есть он находит порядковый номер символа "1", ставит его на первое место, дальше здесь, например, "1" и "1" — одинаковый порядковый номер, он находит порядковый номер "0", порядковый номер "4", "0" идет раньше "4" по этой таблице, "10" уходит вперед и так далее. Естественно, "8" по своему порядковому номеру в таблице, по своему местоположению, идет и позже "1" позже "2", почти позже всех цифр кроме "9", поэтому "8" число у нас получилось позже "28", вряд ли это та сортировка, которую мы хотели получить. Давайте опять попробуем использовать функцию "map". Я здесь прямо наслою функции друг на друга. Обратите внимание, я могу делать прямо матрешку собирать из функций, то есть если это не какое-то очень сложное выражение, если все еще вы можете его прочитать, ничего плохого, если вы не будете создавать промежуточных переменных. Давайте разбирать. Чтобы такую функцию прочитать, мы сначала идем всегда в самый центр и начинаем оттуда ее разбирать. Вот мой список "dates", и я с помощью функции "map", каждую мою строчку превратила в целое число. Обратите внимание, я даже не приводила к промежуточным списку, потому что "sorted" может работать с "map", я просто передаю ему этот объект и получила корректно с нашей точки зрения, как мы ожидали, корректно отсортированный список дат-чисел, потому что с точки зрения Python и это корректно, но вряд ли мы ждали такую сортировку, либо мы можем то же самое, естественно, сделать с помощью метода "key". Сортирую список дат, "key" равно функция "int", перед этапом сортировки создали новый список, где все элементы будут приведены в целые числа, запомни соответствие между оригинальным списком и этим новым, отсортируй новый список, но расставь в этом порядке, те элементы оригинального списка, которые им соответствуют. Соответственно, получилась тоже корректная сортировка, но теперь мы сохранили строковое представление. Последнее, про что мы скажем в этом видео, то что минимум и максимум работают по той же логике, мы с ними уже встречались, когда говорили про списки, соответственно, минимум и максимум в списке чисел, совершенно логично найдут число, которое меньше и которое больше соответственно, а среди строк по той же логике что и сортировка, нам найдут строку, которая идет раньше других в соответствии с таблицей символов или позже. Вот у меня такой пример, список имен и раньше всех по алфавиту идет, мы сейчас узнаем кто и кто идет позже всех. Запускаю эту ячейку и видим, что раньше всех по алфавиту идет "Алена", а позже всех "Таня".