Введение в Python. Часть 9. Сортировка
Как сортировать данные в Python
Данные часто собираются и хранятся в беспорядке, но чтобы проанализировать их, как правило, нужно их сперва отсортировать – по возрастанию или убыванию. В этом выпуске – о том, как устроена сортировка в Python.
Алгоритм Bubble Sort
Есть несколько алгоритмов сортировки, рассмотрим самый простой. Bubble sort или пузырьковая сортировка получила такое название, потому что с ее помощью мы постепенно перемещаем элементы таким образом, что наименьший оказывается в самом начале, так же как пузырек воздуха всплывает в воде наверх. А самый большой элемент, наоборот, опускается вниз – то есть в конец массива.
Этот метод по очереди сравнивает каждые два соседних элемента и переставляет их местами, если порядок неправильный. Например, возьмем следующий ряд чисел: 67381. Сначала алгоритм сравнит первые два соседних числа: 6 меньше 7, значит порядок правильный, они остаются на своих местах. Затем следующие два числа – 7 больше 3, значит они меняются местами. Затем он сравнит 7 и 8, и тоже переставит их местами и так далее. После первого прохода по ряду чисел в конце окажется самое большое число – 8. И дальше алгоритм проходит по всем числам снова и будет проходить столько раз, пока каждое число не встанет на свое место – от меньшего к большему.
Вот как это выглядит на языке Питон. Есть список с числами в рандомном порядке, который нужно отсортировать. Сперва сравним первые два числа и поменяем их местами, если порядок неправильный – то есть второе число больше первого. И попр осим распечатать получившийся список.
Этот код сравнил 6 с 7, и оставил их на своих местах. Теперь сравним следующие два числа: меняем в коде индексы на 1 и 2. И видим, что он сравнил 3 и 7 и поменял их местами.
Эту операцию нам надо выполнять столько раз, сколько у нас в списке чисел, чтобы каждое из них нашло свое место. Поэтому чтобы не прописывать для каждой пары одну и ту же операцию, мы создаем цикл, равный длине нашего массива минус 1, потому что последнее число в списке не имеет соседа справа, и значит эту операцию сравнения производить не нужно. И просим распечатать получившийся список внутри цикла, чтобы видеть каждый шаг кода.
Этот код постепенно переместил 8 в конец, после одного обхода одно число нашло свое правильное место. Но на этом сортировка не заканчивается. Нам нужно, чтобы каждый элемент массива переместился на свое место – значит нужно сделать столько обходов, сколько у нас чисел. Поэтому мы создаем новый цикл с количеством итераций, равным длине списка. Но здесь мы увидим, что на последнем обходе ничего не поменяется, потому что когда 3 нашла свое место, самый минимальный элемент 1 тоже встал на свое место, значит мы можем отнять 1, чтобы не делать последний обход. Как еще можно оптимизировать этот код? После каждого обхода в конце списка оказывается наибольшее число, и сравнение тех чисел, которые уже нашли свое место, производить не надо. Поэтому мы можем отнять внутри цикла количество обходов, соответствующее итерации цикла – run. Тогда код не будет выполнять лишних операций сравнения.
Давайте теперь превратим наш алгоритм в функцию, которой можно будет передавать любые другие массивы. И протестируем ее на новом списке.
Встроенные методы и функции сортировки
В Python есть встроенные функции и методы сортировки, которые позволяют проделать те же операции одной строчкой кода. В большинстве случаев программисты обходятся ими, но алгоритмы, пример которого мы только что протестировали, важно освоить, чтобы понимать механизм работы этих встроенных функций и методов. И в отдельных случаях, когда данных так много, что встроенные функции и методы сортируют их слишком долго, суметь написать более быструю программу.
Метод .sort() сортирует список и сохраняет его в отсортированном виде. А функция sorted() создает новый отсортированный список без изменения исходного.
Еще одно их отличие в том, что функция sorted работает не только со списками, но и другими объектами. Например, вот что получится, если мы отсортируем строку.
Эта функция возвращает список каждый раз, несмотря на то, какой тип данных был ей передан. В случае со словарями, она возвращает отсортированный список словарных ключей.
По умолчанию сортировка будет происходить по возрастанию, но мы можем передавать функции и методу параметры. За это отвечает параметр reverse. Если мы передадим ему параметр True, сортировка будет происходить по убыванию.
Кроме этого, у sort и sorted есть параметр key, который указывает на функцию сравнения. Например, если мы хотим отсортировать значения без учета регистра текста, можно сделать так:
Внутри параметра key могут находиться не только встроенные функции, но и написанные нами. Они обычно нужны, когда мы хотим отсортировать сложный объект. Например, есть такая проблема: если попытаться отсортировать сложный объект (которы й состоит, например, из списка списков), сортировка будет выполняться по первому элементу.
Если мы хотим, чтобы сортировка происходила не по первому элементу, мы можем сами создать специальную функцию.
С помощью функций мы можем производить сортировку и внутри словарей – например, отсортировать эти данные по доходу супруги чиновника из ФСБ.
Теперь вы умеете сортировать данные с помощью Python. Тетрадку этого урока можно скачать на нашем GitHub.