Porównanie kolekcji w Pythonie i Javie. Czyli po co nam słownik w programowaniu?

Jeżeli tak jak ja zaczęliście swoją przygodę z programowaniem od Javy, a potem poznawaliście inne języki, pewnie zwróciliście uwagę na różnicę w kolekcjach (czyli strukturach danych) pomiędzy językami. Może zauważyliście różnice w nazewnictwie, albo w składni, a z czasem skojarzyliście które metody są swoimi odpowiednikami. Postanowiłem wziąć na tapet kolekcje z dwóch popularnych języków – Pythona i Javy – i zrobić małe podsumowanie wiedzy.

Lista, królowa kolekcji!

Lista w Pythonie, podobnie jak w Javie, może przechowywać zduplikowane elementy, oraz może być uporządkowana. W Pythonie do utworzenia listy należy zastosować nawiasy kwadratowe. W Javie najczęściej używamy operatora new i wybieramy konkretną implementację listy lub używamy metody, która te kroki już ma zdefiniowane jak np. Arrays.asList(). Sposoby deklarowanie kolekcji będą podobne również w kolejnych przykładach.

Porównajmy definiowanie list i niektóre z metod wywoływanych na nich.

# Python
list = []  # Zadeklarowanie pustej listy
list.append("Element")  # Dodanie elementu do listy
list.sort()  # Posortowanie listy, bez zwracania nowej
sorted(list, reverse=True)  # Stworzenie nowej posortowanej listy
lastElement = None if not list else list[-1]  # Pobranie ostatniego elementu z listy, chyba że kolekcja jest pusta
// Java
List<String> list = new ArrayList<>(); // Zadeklarowanie pustej listy
list.add("Element"); // Dodanie elementu do listy
list.sort(Comparator.naturalOrder()); // Posortowanie listy, bez zwracania nowej
String lastElement = list.isEmpty() ? null : list.get(list.size()-1); // Pobranie ostatniego elementu z listy, chyba że kolekcja jest pusta

Jak widzicie Python to zupełny inny składniowo język od Javy. Daje możliwość definiowana nowych obiektów bez konieczności użycia operatora new, a także nie wymaga przypisania typu (typowanie dynamiczne). Przy okazji zwróćcie uwagę na różnice w składni operatora warunkowego (pisałem o nim tutaj) między językami.

Zbiory

Zbiory zacząłem doceniać wraz z rozwojem mojej deweloperskiej wiedzy. Teraz nie wyobrażam sobie nie rozważyć użycia zbioru zamiast listy jeżeli wiem, że elementy nie będę się duplikować, a wręcz nie powinny. Oczywiście taka cecha zbioru, jak brak powtarzających się elementów, nie jest zależna od języka i występuje tak w Javie, jak i w Pythonie. Oto krótkie porównanie zbiorów w obu językach.

# Python
set = {1, 1, 2, 3}  # Zadeklarowanie nowego zbioru
set.add(1)  # Dodanie elementu do zbioru
set.discard(1)  # Usunięcie elementu, jeżeli istnieje
set.remove(2)  # Usunięcie elementu, bądź rzucenie wyjątku
# Co otrzymamy?
print(set)
# {3}
// Java
Set<Integer> set = new HashSet<>(); // Zadeklarowanie nowego zbioru
set.add(1); // Dodanie elementu do zbioru
set.add(1);
set.add(2);
set.add(3);
set.remove(1); // Usunięcie elementu
set.remove(4); // Przy braku elementu nie rzuca wyjątku
// Co otrzymamy?
System.out.println(set);
// [2, 3]

Parę rzeczy mogło was tu zdziwić. Po pierwsze, dlaczego nie byłem konsekwentny i nie zadeklarowałem pustego zbioru w Pythonie? Otóż nie tylko zbiory można zadeklarować za pomocą nawiasów klamrowych, a domyślnie puste znaki {} oznaczają przedstawioną w następnym akapicie kolekcję. Dlaczego mogłem dodać do zbioru te same elementy? To zachowanie wydaje się większości oczywiste, ale uwierzcie mi, że można czasem zdziwić się czytając kod i domyślać się, że ktoś chyba pomyślał inaczej. Dodanie zduplikowanego elementu nie rzuci wyjątku, lecz element po prostu nie doda się (lub nadpisze się). Na uwagę natomiast zasługuje metoda remove() w Pythonie, która wyrzuca błąd w przypadku braku elementu w zbiorze. Myślę, że jej świadome zastosowanie będzie w niektórych sytuacjach bardzo przydatne.

Mapy i słowniki

Ten nagłówek oczywiście nie tyczy się oferty księgarni podróżniczej, a dwie nazwy oznaczające kolekcję przechowującą pary klucz-wartość. W Javie mamy do czynienia z mapami, natomiast w Pythonie te kolekcja nazwano słownikami. Przyjrzyjmy się na początek różnicom składniowym:

# Python
dict = {}  # Zadeklarowanie nowego słownika
dict[1] = 'one'  # Dodanie elementu do słownika
dict[2] = 'one'
dict.update({2: 'two'})
dict.pop(1)  # Usunięcie i zwrócenie elementu o kluczu 1, w razie braku rzuca wyjątek
dict.get(2)  # Zwrócenie elementu o kluczu 2, w razie braku nie rzuca wyjątku
# Co otrzymamy?
print(dict)
# {2: 'two'}
// Java
Map<Integer, String> map = new HashMap<>(); // Zadeklarowanie nowej mapy
map.put(1, "one"); // Dodanie elementu do mapy
map.put(2, "one");
map.replace(2, "two"); // Zamiana elementu w mapie
map.get(1); // Zwrócenie elementu o kluczu 1, w razie razie nie rzuca wyjątku
map.remove(1); // Usunięcie elementu o kluczu 1, w razie braku nie rzuca wyjątku
map.remove(2, "one") // Usunięcie elementu o odpowiednim kluczu i wartości, zwraca boolean z rezultatem usunięcia
// Co otrzymamy?
System.out.println(map);
// {2=two}

Mimo różnicy w nazwie słownik i mapa są bardzo do siebie podobne. W obu klucz musi być unikatowy, a dodanie kolejnej wartości z kluczem, który już istnieje nadpisze tę wartość. Jest to podobne zachowanie do zbiorów, bo zaglądając w implementację map i zbiorów w Javie znajdziecie wiele zależności. Zwróćcie też uwagę, że w Pythonie deklaruje się słowniki za pomocą nawiasów klamrowych, czyli tych samych co zbiory i pusta deklaracja oznacza domyślnie właśnie słownik.

Krotka

Krotka to struktura danych, której czasem brakuje mi w Javie. Można oczywiście ją samemu zaimplementować lub skorzystać z bibliotek, ale podoba mi się, że jest dostępna od ręki w Pythonie. Krotka to po prostu niemutowalna (niedytowalna) kolekcja. Odwołujemy się do niej po indeksie. Co ważne może przechowywać różne typy danych. Dzięki krotce zamiast tworzyć jakaś klasę danych (ang. data class) np. Person tylko po to by przechować imię, nazwisko i PESEL można użyć krotki = "Pawel", "Nowak", 82113003033.

tuple = 1, "two", False, {1: "dict"}
tuple[0]

To oczywiście tylko krótkie przejście po temacie struktur danych i ich różnic między Pythonem i Javą. Jednak, mam nadzieję, że uczącym się takie porównanie pomoże.

Porównanie kolekcji w Pythonie i Javie. Czyli po co nam słownik w programowaniu?

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Przewiń do góry