Cześć! Przygotowałem dla Ciebie już czwarty wpis z serii „Struktury danych w Pythonie”. Tym razem zajmiemy się słownikiem, czyli dictionary, a w skrócie po prostu dict.
Jest to jedna z najważniejszych i najczęściej używanych struktur w Pythonie. W poprzednich wpisach mówiliśmy o listach, krotkach i zbiorach. Mają one to do siebie, że przechowują pojedyncze wartości, np. liczbę, ciąg znaków albo obiekt.
Słownik natomiast jest strukturą przechowującą pary klucz-wartość. W innych językach takie struktury noszą czasem nazwę map albo tablic asocjacyjnych. Jak nazwa wskazuje, przechowują one asocjację, czyli związek między dwoma bytami – kluczem i wartością.
Ok, wystarczy tego wstępu, przejdźmy do rzeczy 😉
Charakterystyka słowników w Pythonie
Słownik (dict) w Pythonie posiada następujące cechy:
- Jest zmienny (modyfikowalny, mutowalny), czyli możemy dowolnie dodawać, usuwać oraz modyfikować jego elementy.
- Nie gwarantuje zachowania kolejności elementów (jeśli bardzo zależy nam na kolejności elementów to możemy skorzystać z
collections.OrderedDict
). - Indeksem słownika jest jego klucz
- Klucz musi być niezmienny, czyli może nim być np. liczba lub string.
- Krotka jest niezmienna i również może być kluczem, ale tylko jeśli zawiera w sobie wyłącznie stringi, liczby i inne krotki. Jeśli zawiera w sobie jakieś zmienne obiekty to nie może być kluczem.
- Będąc bardziej dokładnym, klucz musi być hashowalny, czyli spełniać dokładnie takie same kryteria, jak elementy zbioru, czyli set-u. Kwestię tego, czym jest hashowalność, szczegółowo omówiłem w artykule o zbiorach.
- Klucz musi być unikalny – w jednym słowniku nie może być więcej niż jeden taki sam klucz.
- Wartością w słowniku może być dowolny obiekt.
- Wartości różnych kluczy mogą mieć różne typy, np. dla jednego klucza wartość to będzie string, a dla innego lista.

Inicjalizacja
Aby utworzyć nowy, pusty słownik możemy wykorzystać literał, jakim są nawiasy klamrowe {}
, albo skorzystać z konstruktora dict()
:
>>> empty = {} >>> empty {} >>> type(empty) <class 'dict'>
>>> empty = dict() >>> empty {} >>> type(empty) <class 'dict'>
Jeśli chcemy uzyskać słownik zawierający na starcie konkretne dane, to wewnątrz nawiasów kwadratowych musimy umieścić pary klucz: wartość
(rozdzielone średnikiem i, w zgodzie z Pythonową konwencją, także spacją), oddzielone od siebie przecinkami.
W ostatnim czasie jestem zajarany serialem o Formule 1 na Netflixie, dlatego bohaterami dzisiejszego artykułu o słownikach będą kierowcy F1 oraz ich numery startowe 😉 Jeśli interesuje Cię, skąd wzięły się te numery, to znalazłem ciekawy artykuł, który to wyjaśnia.
drivers = { "Lewis Hamilton": 44, "Sebastian Vettel": 5, "Carlos Sainz": 55, "Daniel Ricciardo": 3, }
W powyższym przykładzie stworzyłem słownik, gdzie kluczem są imię i nazwisko kierowcy, a wartością jego numer startowy.
Tak jak przy pustym słowniku, tutaj też mogę użyć konstruktora dict()
. Podaję wtedy do niego iterable, czyli na przykład listę, zawierającą nasze pary klucz-wartość opakowane w krotki:
drivers = dict([("Lewis Hamilton", 44), ("Sebastian Vettel", 5), ("Carlos Sainz", 55), ("Daniel Ricciardo", 3)])
Jest jeszcze trzeci, całkiem „sprytny” sposób. Możemy użyć dict()
, ale dane podać do środka jako keyword arguments, czyli „argumenty nazwane”. Zadziała to jednak tylko wtedy, gdy naszymi kluczami są proste jednowyrazowe stringi. Dlatego musielibyśmy nasz przykład uprościć i użyć samych nazwisk zawodników:
drivers = dict(Hamilton=44, Vettel=5, Sainz=55, Ricciardo=3)
W zależności od sytuacji możesz skorzystać z tego sposobu, który jest akurat dla Ciebie wygodniejszy. Z mojego doświadczenia mogę Ci powiedzieć, że pierwszy sposób z użyciem nawiasów klamrowych jest zdecydowanie najczęściej stosowany.
Operacje na słownikach
Podstawowe operacje
Aby sprawdzić, ile elementów zawiera nasz dict, standardowo użyjemy funkcji len()
, tak samo jak w przypadku poprzednio omawianych kolekcji.
>>> len(drivers) 4
Do otrzymania listy wszystkich kluczy w naszym słowniku możemy podać słownik jako argument do konstruktora list()
:
>>> list(drivers) ['Lewis Hamilton', 'Sebastian Vettel', 'Carlos Sainz', 'Daniel Ricciardo']
Pobieranie wartości
Słowniki są indeksowane po kluczach. Oznacza to, że aby wyciągnąć wartość odpowiadającą danemu kluczowi, użyjemy składni podobnej do list czy krotek, ale zamiast indeksu liczbowego podamy nasz klucz:
>>> drivers["Carlos Sainz"] 55
Jeśli klucz, którego użyjemy, nie istnieje w słowniku, otrzymamy KeyError
:
>>> drivers["Robert Kubica"] Traceback (most recent call last): File "<input>", line 1, in <module> KeyError: 'Robert Kubica'
Możesz uniknąć tego sprawdzając najpierw, czy dany klucz istnieje w słowniku:
>>> "Robert Kubica" in drivers False
Jednak jest też inny sposób na uniknięcie błędu. Możesz skorzystać z metody get()
wywoływanej na obiekcie słownika. Jeśli klucz istnieje, to otrzymasz jego wartość, a jeśli nie, to otrzymasz po prostu None
:
>>> drivers.get("Robert Kubica") # None >>> drivers.get("Lewis Hamilton") 44
Ciekawym trikiem jest to, że jako drugi argument możemy tutaj podać wartość domyślną (default
), która zostanie zwrócona w przypadku jeśli klucz nie zostanie odnaleziony w słowniku:
>>> drivers.get("Robert Kubica", 0) 0 >>> drivers.get("Lewis Hamilton", 0) 44
Dodawanie i edycja elementów
Umówmy się, że oglądanie ciągle tych samych kierowców może być nużące. Dlatego dobrze by było poszerzyć naszą wesołą gromadkę o nowych zawodników 🏎
Dodanie nowej pary klucz-wartość do słownika wygląda podobnie do pobierania wartości dla klucza. W nawiasie kwadratowym podajemy klucz, a po znaku „=
” przypisujemy mu odpowiednią wartość:
>>> drivers["Lando Norris"] = 4 >>> drivers {'Lewis Hamilton': 44, 'Sebastian Vettel': 5, 'Carlos Sainz': 55, 'Daniel Ricciardo': 3, 'Lando Norris': 4}
Ale uwaga! Jeśli wpis o danym kluczu już istnieje w słowniku, to jego wartość zostanie nadpisana! Zauważ jak poniżej nadpisuję numer startowy Vettela:
>>> drivers["Sebastian Vettel"] = 5555 >>> drivers {'Lewis Hamilton': 44, 'Sebastian Vettel': 5555, 'Carlos Sainz': 55, 'Daniel Ricciardo': 3}
Tym samym wiesz już jak edytować wartość w słowniku dla danego klucza – dokładnie tak samo, jak gdybyś dodawał nową parę do słownika.
Usuwanie elementów
Jeśli któryś z kierowców powoduje za dużo problemów na torze, to należałoby go dyscyplinarnie usunąć z wyścigu. Na szczęście w przypadku słownika wystarczy skorzystać z polecenia del
:
>>> del drivers["Daniel Ricciardo"] >>> drivers {'Lewis Hamilton': 44, 'Sebastian Vettel': 5, 'Carlos Sainz': 55, 'Lando Norris': 4}
Co jeśli klucz nie istnieje? Musimy przygotować się na wyjątek:
>>> del drivers["Robert Kubica"] Traceback (most recent call last): File "<input>", line 1, in <module> KeyError: 'Robert Kubica'
Jak sobie z tym poradzić? Możemy najpierw sprawdzić, czy klucz istnieje w słowniku za pomocą in
– mówiliśmy o tym wyżej. Innym sposobem będzie opakowanie naszego wywołania del
w blok try / except i złapanie tego wyjątku:
try: del drivers["Robert Kubica"] except KeyError: print("Driver not found.")
Możemy również do usunięcia elementu ze słownika skorzystać z metody pop()
. Tutaj też w przypadku braku szukanego klucza otrzymamy KeyError
, choć… niekoniecznie 😉 Bo możemy zdefiniować wartość domyślną, podobnie jak to było wyżej w przypadku get()
, i to właśnie ona zostanie zwrócona przy braku szukanego klucza. Taką wartością domyślną może też być na przykład None
:
>>> drivers.pop("Lewis Hamilton", None) 44 >>> drivers.pop("Robert Kubica", None). # Otrzymaliśmy None >>> drivers {'Sebastian Vettel': 5, 'Carlos Sainz': 55, 'Lando Norris': 4}
Jak widzisz powyżej, używając pop()
, podobnie jak to było przy listach i zbiorach, nie tylko usuwamy element ze struktury danych, ale również otrzymujemy go z powrotem i możemy z niego skorzystać. W przypadku słownika nie otrzymujemy z powrotem całej pary klucz-wartość, a jedynie samą wartość, jak widać powyżej – pop
-ując Lewisa Hamiltona ze słownika dostaliśmy w odpowiedzi 44
, czyli jego wartość.
Iterowanie po słowniku
Najprostszym sposobem iteracji po wszystkich elementach słownika jest wykorzystanie pętli for i podanie do niej po prostu obiektu naszego słownika:
drivers = { "Lewis Hamilton": 44, "Sebastian Vettel": 5, "Carlos Sainz": 55, "Daniel Ricciardo": 3, } for driver in drivers: print(driver) ### Wynik: Lewis Hamilton Sebastian Vettel Carlos Sainz Daniel Ricciardo
Python jest sprytny i wykrywa, że podaliśmy mu słownik i wie, że ma iterować po kluczach. Dlatego wewnątrz pętli każdy obiekt driver
to klucz naszego słownika.
Jeśli chcemy operować na wartościach, musimy wewnątrz pętli użyć zwykłej operacji pobrania wartości, którą poznaliśmy wyżej:
for driver in drivers: print(driver, ":", drivers[driver]) ### Wynik: Lewis Hamilton : 44 Sebastian Vettel : 5 Carlos Sainz : 55 Daniel Ricciardo : 3
Innym sposobem jest wykorzystanie metody items()
, która zwraca tzw. „widok” elementów słownika. Jest to dynamiczny obiekt – jeśli coś się zmieni w słowniku, coś zostanie dodane, zmienione lub usunięte – to widok będzie odzwierciedlał te zmiany.
Oto co zobaczymy jeśli przeiterujemy po drivers.items()
:
for driver in drivers.items(): print(driver) ### Wynik: ('Lewis Hamilton', 44) ('Sebastian Vettel', 5) ('Carlos Sainz', 55) ('Daniel Ricciardo', 3)
Kojarzysz, czym jest pojedyńczy element w pętli? Właśnie dlatego słowniki omawiamy jako ostatnie spośród podstawowych struktur danych w Pythonie, bo do ich pełnego zrozumienia warto znać te poprzednie. Dlatego, że mamy tu do czynienia po prostu z krotkami 😉
for driver in drivers.items(): print(driver) print(type(driver)) ### Wynik: ('Lewis Hamilton', 44) <class 'tuple'> ('Sebastian Vettel', 5) <class 'tuple'> ('Carlos Sainz', 55) <class 'tuple'> ('Daniel Ricciardo', 3) <class 'tuple'>
Wiedząc o tym, że są to krotki, możemy zastosować tuple unpacking, który też już znasz jeśli czytałeś wpis o krotkach, i oto co otrzymamy:
for driver, number in drivers.items(): print(driver, ":", number) ### Wynik: Lewis Hamilton : 44 Sebastian Vettel : 5 Carlos Sainz : 55 Daniel Ricciardo : 3
Całkiem zgrabnie to wygląda, prawda? 😉
Podsumowanie
Tutaj się na dzisiaj zatrzymamy, choć o słownikach można by mówić jeszcze dłuuugo! Ale jeśli opanujesz operacje na słownikach, które przedstawiłem w tym artykule, to wystarczy Ci to do 90% przypadków użycia słowników.
Jeśli jednak chcesz poznać dodatkowe triki przydatne w tych pozostałych 10%, to daj znać 🙂 Napisz jakiś komentarz pod tym artykułem albo udostępnij go w social mediach i oznacz mnie w tym poście (Facebook, Instagram, Twitter) – będzie to dla mnie sygnał, że warto cisnąć dalej tego typu materiały 💪
Jeśli jeszcze Cię tam nie ma, to koniecznie dołącz do mojego newslettera! Co tydzień dostaniesz ode mnie zestaw ciekawych linków z branży i będziesz jako pierwszy dowiadywał się o wszystkich moich nowych inicjatywach z zakresu edukacji w IT 😀