PY_I_R_W13A_M04 Wbudowane funkcje sortowania
Podczas omawiania funkcji sortowania dostępnych w poszczególnych językach programowania skupimy się na dostępnych w nich klasach i funkcjach wbudowanychfunkcjach wbudowanych, związanych z algorytmami sortowania.
W zależności od języka programowania funkcje sortujące wywoływane są poprzez podanie ich nazwy, np. sort() lub poprzez podanie klasy albo obiektu i nazwy, np. Arrays.sort() lub lista.sort(). W tym drugim przypadku należy posługiwać się terminem metoda, który oznacza składową funkcję klasy. W tym e‑materiale będziemy zachowywać to rozróżnienie.
Funkcje w języku Python
sorted()
Funkcja sorted() jest częścią biblioteki standardowej języka Python i wykorzystywana jest do porządkowania danych różnych typu. Mogą to być np. listy, krotki, ciągi znaków, słowniki czy zbiory.
Podczas sortowania funkcja korzysta z algorytmu timsorttimsort, nie modyfikuje sortowanych obiektów, ale zwraca nową posortowaną listę. Zastosowany algorytm gwarantuje stabilność sortowania.
Oto przykład porządkowania listy liczb. Warto zwrócić uwagę, że w drugim wywołaniu funkcji używamy dodatkowego argumentu reverse.
Wynik działania programu:
Dana jest lista liczb: lista = [5, 8, -3, 1, 10, 3.14, 18]. Podaj ciąg wywołań instrukcji sorted(), który po wykonaniu spowoduje wypisanie następujących komunikatów:
Funkcja sorted() umożliwia określanie własnych kryteriów sortowania za pomocą opcjonalnego argumentu key. Zapoznajmy się z przykładami.
Jeżeli jako argument key, tj. klucz, podamy wartość None lub w ogóle go nie podamy, zastosowane zostanie sortowanie domyślne, tj. niemalejąco.
W poniższym przykładzie będzie to porządkowanie alfabetyczne słów według kodów znaków, dlatego wyrazy pisane wielkimi literami znajdą się na początku zwróconej listy.
Wynik działania programu:
W poniższym kodzie jako argumentu key używamy funkcji anonimowejfunkcji anonimowej wprowadzanej przez słowo kluczowe lambda. Funkcja wykonywana jest na każdym elemencie listy przekazywanym w argumencie element przed posortowaniem i zwraca klucz, tj. wartość wykorzystywaną do sortowania.
W tym przypadku jest to wartość True, jeżeli element jest liczbą parzystą, czyli jest większy, lub False w przeciwnym przypadku, czyli gdy jest mniejszy. Dlatego w posortowanej liście liczby nieparzyste będą poprzedzały parzyste.
Wynik działania programu:
Zapoznajmy się z przykładem programu, który porządkuje wyrazy zapisane w ciągu znaków niemalejąco pod względem ich długości.
Wynik działania programu:
Metoda split() dzieli ciąg znaków na podciągi, wykorzystując znaki białe (spacje, tabulatory) i zwraca ich listę. Listę sortujemy, wskazując w argumencie key jako kryterium funkcję len(), która zwraca ich długość.
Zmień wywołania funkcji sorted(), tak aby odwrócić porządek sortowania.
Wynik działania programu:
Argumentu key często używa się do porządkowania danych składających się z wielu wartości. Jedna z wartości wybrana zostaje jako klucz sortowania. Takie dane zapisane mogą być w różnych strukturach, np. w krotkach lub słownikach, mogą również być atrybutami obiektów będących instancjami klas użytkownika.
Poniżej pokażemy przykłady sortowania danych uczniów składających się z imion i wieku niemalejąco według wieku ucznia.
Zacznijmy od przykładu, w którym dane uczniów zapisano w krotkach. Listę krotek sortujemy w porządku niemalejącym wg założonego kryterium, tj. według wieku uczniów.
Sortowane krotki przekazywane są do funkcji anonimowej (lambda), która jako klucz zwraca ich drugi element (uczen[1]), tj. wiek ucznia.
Wynik działania programu:
W kolejnym przykładzie imiona i wiek uczniów zapisane są w słownikach. Listę słowników porządkujemy niemalejąco według wieku uczniów.
Do funkcji anonimowej przekazywany jest każdy słownik w zmiennej uczen. Wyrażenie uczen["wiek"] pozwala wskazać wiek ucznia, który zostaje wykorzystany jako klucz sortowania.
Wynik działania programu:
Ostatni przykład pokazuje sortowanie listy obiektów utworzonych na podstawie klasy Uczen, która ma dwa atrybuty, czyli imie i wiek. Listę obiektów porządkujemy niemalejąco według wieku ucznia.
Podobnie jak w poprzednich przykładach w funkcji anonimowej, do której trafia każdy obiekt w zmiennej uczen, możemy wskazać kryterium sortowania, tj. atrybut związany z wiekiem: uczen.wiek.
W definicji klasy metoda specjalna __repr__() wykorzystywana jest do zwrócenia reprezentacji obiektu, w tym przypadku do wypisania jego atrybutów, tj. imienia i wieku ucznia.
Wynik działania programu:
Podczas sortowania możemy również używać funkcji porównującej (komparatora), która powinna zwracać wartość mniejszą od 0, jeżeli pierwszy element jest mniejszy od drugiego; wartość większą od 0, w przeciwnym przypadku lub wartość 0, kiedy elementy są równe. Użycie funkcji porównującej daje nam możliwość określania własnych reguł, które decydują, który z dwóch elementów uznajemy za większy.
Do wskazania funkcji porównującej w argumencie key wykorzystujemy funkcję cmp_to_key() z modułu functools. Jej argumentem jest nazwa funkcji porównującej.
Oto przykład użycia funkcji cmp_to_key() do wskazania funkcji porównującej o nazwie porownaj() dla argumentu key:
Wynik działania programu:
Wypisywane komunikaty oznaczają, że funkcja porownaj() otrzymuje pary liczb, które mają być uporządkowane. Funkcja zwraca wartość -1, jeżeli warunek a % 2 == 1 and b % 2 == 0 jest prawdziwy, czyli pierwsza liczba (a) jest parzysta i mniejsza od drugiej liczby parzystej (b), która jest większa. W pozostałych przypadkach zwracana jest wartość 1, co oznacza, że pierwsza liczba (a) jest większa.
W efekcie otrzymujemy listę, w której na początku znajdują się uporządkowane niemalejąco liczby nieparzyste, a potem również uporządkowane niemalejąco liczby parzyste.
list.sort()
Biblioteka standardowa zawiera również definicję funkcji sort() dostępnej jako metoda każdej listy. Metoda ta nie zawraca nowej listy, natomiast modyfikuje kolejność elementów listy, na rzecz której jest wywoływana. Wykorzystuje wspominany już algorytm stabilnego sortowania hybrydowego TimsortTimsort.
W metodzie sort() możemy korzystać z dwóch opcjonalnych nazwanych argumentów, tj. reverse oraz key. Ich działanie jest takie samo jak w przypadku funkcji sorted(). Poniżej zamieszczamy kilka przykładów.
Domyślne sortowanie listy liczb całkowitych niemalejąco z użyciem metody sort(), która modyfikuje początkową listę.
Wynik działania programu:
Sortowania listy liczb całkowitych nierosnąco z użyciem metody sort(). Dodatkowy argument reverse ustawiony na wartość True pozwala uzyskać sortowanie nierosnące.
Wynik działania programu:
Sortowanie listy liczb całkowitych nierosnąc0 z użyciem metody sort(). Podobnie jak w przypadku omawianej wyżej funkcji sorted(), w przykładzie używamy dodatkowego argumentu key i funkcji anonimowej lambda. Funkcja zwraca wartość True, jeżeli sortowana liczba jest parzysta, co oznacza, że należy traktować ją jako większą niż liczba nieparzysta, dla której funkcja zwraca wartość False. W ten sposób uzyskamy takie samo uporządkowanie jak w omawianym wyżej przykładzie użycia własnej funkcji porównującej, tzn. wartości uporządkowane zostaną niemalejąco, ale na początku znajdą się liczby nieparzyste, a potem parzyste.
Wynik działania programu:
Funkcja sorted() jest przydatna, gdy chcemy uzyskać posortowaną kopię listy. Metody sort() użyjemy, kiedy chcemy posortować listę początkową, bez tworzenia jej kopii.
Słownik
biblioteka dostarczana z kompilatorem lub interpreterem danego języka programowania, zawierająca jego podstawowe funkcje i typy danych
funkcje danego języka programowania dostępne dla programisty w dowolnym momencie wykonywania programu
definicja funkcji bez nazwy, której używa się zazwyczaj raz; w języku Python używa się składni: lambda argumenty: wyrażenie; funkcja może mieć wiele argumentów, natomiast tylko jedno wyrażenie, którego wynik zwraca
złożona struktura danych służąca do przechowywania obiektów udostępniająca metody pozwalające na dodawanie, odczytywanie, usuwanie, modyfikowanie czy wyszukiwanie danych, przykładem może być tablica lub lista
instancja jakiejś klasy definiującej złożony typ danych, zawiera pola z danymi (atrybuty) oraz funkcje wykonujące operacje na tych danych, zwane metodami
stabilny algorytm sortowania łączący cechy sortowania przez wstawianie i przez scalanie; wyszukuje w danych już posortowane sekwencje i wykorzystuje je do wydajniejszego sortowania pozostałych danych
algorytm stabilny podczas porządkowania dwóch takich samych elementów zachowuje ich porządek wejściowy w uporządkowanym zbiorze wynikowym, algorytm niestabilny nie gwarantuje zachowania takiego porządku