
Słownik Python – najważniejsze pojęcia i definicje dla początkujących
Praca z danymi bardzo szybko pokazuje, że same zmienne i listy przestają wystarczać. Gdy trzeba powiązać konkretną wartość z nazwą, identyfikatorem, adresem e-mail, numerem produktu albo statusem zamówienia, potrzebna jest struktura oparta nie na pozycji elementu, ale na kluczu. Dzięki temu odczyt danych jest szybszy, kod czytelniejszy i łatwiej uniknąć błędów związanych z indeksami. Najwygodniejszym punktem startu do zrozumienia pracy z danymi w Pythonie pozostaje Słownik Python.
Spis Treści
Słownik Python jako struktura mapująca klucze na wartości i różnica względem listy
Słownik (dictionary, dict) to wbudowana struktura danych oparta na parach klucz: wartość. Zamiast pytać program „co jest na pozycji numer 3”, pytamy „jaka wartość jest przypisana do klucza email”.
To fundamentalna różnica względem listy.
Lista:
- zachowuje kolejność
- używa indeksów liczbowych
- dobrze nadaje się do sekwencji danych
Słownik:
- używa unikalnych kluczy
- pozwala szybko znaleźć wartość po nazwie
- dobrze nadaje się do danych opisowych i konfiguracyjnych
Przykład praktyczny:
Dla użytkownika systemu zamiast:
- indeks 0 = imię
- indeks 1 = nazwisko
- indeks 2 = wiek
bezpieczniej jest użyć:
"imie"= Jan"nazwisko"= Kowalski"wiek"= 29
W kodzie oznacza to mniej pomyłek. Po miesiącu łatwiej zrozumieć uzytkownik["wiek"] niż uzytkownik[2].
Klucze muszą być hashowalne, czyli niezmienne. Najczęściej używa się:
strintfloattuple(jeśli zawiera niezmienne elementy)
Nie używa się jako kluczy:
- list
- innych słowników
- zbiorów
set
bo są mutowalne.
Podstawowa składnia tworzenia i odczytu danych
| Operacja | Przykład kodu |
|---|---|
| Utworzenie słownika | python\nstudent = {\n \"imie\": \"Anna\",\n \"wiek\": 21,\n \"kierunek\": \"Informatyka\"\n}\n |
| Odczyt wartości | python\nprint(student[\"imie\"])\n |
| Zmiana wartości | python\nstudent[\"wiek\"] = 22\n |
| Dodanie nowego pola | python\nstudent[\"rok\"] = 2\n |
Odpowiednik idei w C++ i C
Python ma słownik wbudowany, ale ta sama logika istnieje także w innych językach.
| Język | Przykład |
|---|---|
C++ (unordered_map) | cpp\n#include <iostream>\n#include <unordered_map>\nusing namespace std;\n\nint main() {\n unordered_map<string, int> wiek;\n wiek[\"Anna\"] = 21;\n cout << wiek[\"Anna\"] << endl;\n return 0;\n}\n |
| C (prosta symulacja) | c\n#include <stdio.h>\n#include <string.h>\n\nstruct Student {\n char klucz[20];\n int wartosc;\n};\n\nint main() {\n struct Student s;\n strcpy(s.klucz, \"wiek\");\n s.wartosc = 21;\n printf(\"%d\\n\", s.wartosc);\n return 0;\n}\n |
C nie ma wbudowanego słownika, więc zwykle używa się własnych struktur lub bibliotek z tablicami haszującymi.
Najważniejsze operacje, które wykonuje się codziennie podczas pracy ze strukturą Słownik Python
W praktyce nie chodzi o samo utworzenie słownika, ale o bezpieczne pobieranie danych, iterację i kontrolę błędów.
Najwięcej problemów początkujący mają właśnie tutaj.
Dostęp przez nawiasy kwadratowe i problem KeyError
Kod:
print(student["email"])
zadziała tylko wtedy, gdy klucz istnieje.
Jeśli nie istnieje, Python zgłosi:
KeyError
To częsty błąd w aplikacjach webowych, parserach JSON i automatyzacji plików.
Bezpieczniejsze jest użycie .get().
| Metoda | Przykład |
|---|---|
| Ryzykowny odczyt | python\nprint(student[\"email\"])\n |
| Bezpieczny odczyt | python\nprint(student.get(\"email\"))\n |
| Wartość domyślna | python\nprint(student.get(\"email\", \"brak\"))\n |
To drobiazg, ale oszczędza dużo czasu przy debugowaniu.
Iteracja po kluczach, wartościach i parach
Słownik można przeglądać na kilka sposobów.
| Cel | Kod |
|---|---|
| Same klucze | python\nfor k in student:\n print(k)\n |
| Same wartości | python\nfor v in student.values():\n print(v)\n |
| Klucz i wartość | python\nfor k, v in student.items():\n print(k, v)\n |
Najczęściej używa się .items().
Kod jest wtedy czytelny i nie wymaga dodatkowego odwołania student[k].
Usuwanie elementów i kontrola istnienia klucza
| Operacja | Kod |
|---|---|
Usunięcie przez del | python\ndel student[\"rok\"]\n |
Usunięcie przez pop() | python\nstudent.pop(\"rok\")\n |
| Sprawdzenie klucza | python\nif \"wiek\" in student:\n print(\"istnieje\")\n |
pop() jest wygodniejsze, bo może zwrócić usuwaną wartość.
Złożoność czasowa i dlaczego słownik jest szybki
W typowym przypadku:
- odczyt: O(1)
- zapis: O(1)
- usunięcie: O(1)
Lista dla wyszukiwania po wartości zwykle wymaga:
- O(n)
To duża różnica.
Dla 10 elementów nie ma znaczenia. Dla 500 000 rekordów już bardzo.
Powodem jest użycie tablicy haszującej.
Uproszczony model działania funkcji hash
| Etap | Opis |
|---|---|
| 1 | Python oblicza hash klucza |
| 2 | Hash wskazuje miejsce w pamięci |
| 3 | Program trafia bezpośrednio do wartości |
To właśnie daje szybkość.
Nie jest to magia, tylko dobra organizacja danych.
Pułapki wydajnościowe, dobre praktyki i sytuacje, w których Słownik Python nie jest najlepszym wyborem
Słownik jest bardzo wygodny, ale nie zawsze najlepszy.
Zbyt częste używanie go „bo jest uniwersalny” też bywa błędem.
Duplikaty kluczy nie istnieją
To ważne.
Kod:
| Przykład | Kod |
|---|---|
| Powielony klucz | python\ndane = {\n \"id\": 1,\n \"id\": 2\n}\nprint(dane)\n |
wynikiem będzie:
{'id': 2}Druga wartość nadpisuje pierwszą.
Jeśli potrzebne są wielokrotne wartości, lepiej użyć:
- listy w słowniku
defaultdict- bazy danych
- struktury relacyjnej
Zagnieżdżone słowniki i czytelność kodu
Przykład:
| Kod |
|---|
python\nfirma = {\n \"pracownik\": {\n \"imie\": \"Jan\",\n \"adres\": {\n \"miasto\": \"Warszawa\"\n }\n }\n}\n |
Dostęp:
firma["pracownik"]["adres"]["miasto"]
Technicznie poprawne, ale po kilku poziomach zaczyna być trudne w utrzymaniu.
W większych projektach często lepiej przejść na:
- klasy
- dataclass
- Pydantic
- ORM
bo struktura staje się przewidywalna.
Liczenie częstości występowania danych
To bardzo częsty przypadek.
Na przykład analiza logów:
- ile razy wystąpił błąd 404
- ile razy pojawił się użytkownik
- ile razy wystąpiło konkretne słowo
| Kod |
|---|
python\ntekst = [\"a\", \"b\", \"a\", \"c\", \"a\"]\nlicznik = {}\n\nfor x in tekst:\n licznik[x] = licznik.get(x, 0) + 1\n\nprint(licznik)\n |
To klasyczny wzorzec.
W praktyce spotyka się go bardzo często na rozmowach technicznych.
Wzór logiczny licznika
| Zastosowanie | Zapis |
|---|---|
| Aktualizacja licznika | nowa_wartosc = stara_wartosc + 1 |
| Wersja z wartością domyślną | dict.get(klucz, 0) + 1 |
Niby proste, ale bez tego trudno pisać sensowne przetwarzanie danych.
Przykłady praktyczne z codziennej pracy programisty i administratora danych
Najbardziej naturalne zastosowania:
- konfiguracje aplikacji
- dane z API w formacie JSON
- cache wyników
- mapowanie identyfikatorów
- liczniki i statystyki
- parametry użytkownika
- słowniki tłumaczeń
- walidacja formularzy
JSON praktycznie jest bliskim odpowiednikiem słownika.
Przykład:
| JSON / Python |
|---|
python\nzamowienie = {\n \"id\": 150,\n \"status\": \"oplacone\",\n \"kwota\": 249.99\n}\n |
Dlatego dobra znajomość tej struktury jest obowiązkowa przy:
- backendzie
- analizie danych
- automatyzacji
- DevOps
- testach API
Bez tego szybko pojawia się chaos.
FAQ dotyczące pracy ze słownikami w Pythonie i najczęstszych problemów początkujących
Czy słownik zachowuje kolejność elementów?
Od Python 3.7 tak – kolejność dodawania elementów jest zachowywana. W starszych wersjach nie należało na tym polegać.
Czy klucz może być liczbą?
Tak. Kluczem może być int, float, str, tuple i inne typy hashowalne.
Dlaczego pojawia się KeyError?
Bo program próbuje odczytać nieistniejący klucz przez zapis dict["klucz"]. Bezpieczniej używać get().
Kiedy lepiej użyć listy zamiast słownika?
Gdy dane mają naturalną kolejność i dostęp odbywa się przez pozycję, nie przez nazwę.
Czy słownik jest szybszy od listy?
Przy wyszukiwaniu po kluczu zazwyczaj tak, ponieważ średnia złożoność to O(1). Przy prostym przechodzeniu po elementach różnica może być mała.
Czy można sortować słownik?
Tak, zwykle przez funkcję sorted() oraz sortowanie po kluczach albo wartościach.
| Przykład |
|---|
python\nfor k in sorted(student):\n print(k, student[k])\n |
Słownik jest jedną z tych struktur, które wydają się proste tylko na początku. Później okazuje się, że od jakości pracy z nim zależy czytelność całego programu, liczba błędów i czas potrzebny na utrzymanie kodu. Dobrze używany porządkuje projekt, źle używany tworzy bałagan, który wraca po kilku miesiącach ze zdwojoną siłą.
Źródło Foto: Freepik


