Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

Słowniki - Katalogowanie odkryć

Witaj ponownie, @name! Darwin tutaj z kolejną ważną lekcją.

W poprzedniej lekcji nauczyłeś/aś się list - uporządkowanych kolekcji jak szlaki ekspedycji. Ale czasem potrzebujesz czegoś więcej - sposobu na katalogowanie swoich odkryć z dodatkowymi informacjami. W dżungli każdy gatunek ma swoją kartę z danymi: siedlisko, wielkość, czy jest niebezpieczny. W Pythonie używamy do tego słowników (dictionaries).

Czym są słowniki?

Słownik to kolekcja par klucz: wartość. Wyobraź sobie katalog odkryć, gdzie każdy gatunek (klucz) ma swoją kartę z informacjami (wartość).

1# Katalog gatunku - klucz to nazwa, wartość to szczegóły
2species_info = {
3    "Python regius": "Pyton królewski, 1-2m, niegroźny",
4    "Panthera leo": "Lew, 2-3m, bardzo niebezpieczny",
5    "Loxodonta africana": "Słoń afrykański, 3-4m, spokojny"
6}
7
8# Bardziej złożony katalog
9detailed_catalog = {
10    "Python regius": {
11        "nazwa_pl": "Pyton królewski",
12        "długość_m": 1.5,
13        "habitat": "jungle",
14        "niebezpieczny": False
15    },
16    "Panthera leo": {
17        "nazwa_pl": "Lew",
18        "długość_m": 2.5,
19        "habitat": "savanna",
20        "niebezpieczny": True
21    }
22}

Kluczowe cechy słowników:

  • Pary klucz-wartość - każdy klucz prowadzi do wartości
  • Nieuporządkowane (Python 3.7+: zachowują kolejność wstawiania)
  • Klucze muszą być unikalne i niemutowalne (string, int, tuple)
  • Wartości mogą być dowolne - nawet inne słowniki!
  • Mutable - można je modyfikować

Tworzenie słowników

1# Pusty słownik - czysty katalog
2empty_catalog = {}
3empty_dict = dict()
4
5# Słownik z danymi
6explorer_data = {
7    "imię": "Darwin",
8    "wiek": 35,
9    "zawód": "Badacz",
10    "odkrycia": 47
11}
12
13# Różne typy kluczy (ale najczęściej stringi)
14mixed_keys = {
15    "name": "Python",
16    42: "Odpowiedź",
17    (10, 20): "Współrzędne"
18}
19
20# Zagnieżdżone słowniki
21expedition = {
22    "lokalizacja": "Amazonia",
23    "zespół": {
24        "lider": "Darwin",
25        "liczba": 5
26    },
27    "ekwipunek": ["Lornetka", "Mapa", "GPS"]
28}
29
30# dict() constructor
31from_pairs = dict([("A", 1), ("B", 2), ("C", 3)])
32with_kwargs = dict(name="Darwin", age=35, job="Explorer")

Dostęp do wartości

1species = {
2    "Python regius": "Pyton królewski",
3    "Panthera leo": "Lew",
4    "Loxodonta africana": "Słoń"
5}
6
7# Dostęp przez klucz (nawiasy kwadratowe)
8python_name = species["Python regius"]  # "Pyton królewski"
9lion_name = species["Panthera leo"]     # "Lew"
10
11# KeyError jeśli klucz nie istnieje!
12# wrong = species["Tyrannosaurus"]  # KeyError!
13
14# Bezpieczny dostęp - get()
15python_name = species.get("Python regius")  # "Pyton królewski"
16trex = species.get("Tyrannosaurus")         # None
17trex = species.get("Tyrannosaurus", "Nie znaleziono")  # "Nie znaleziono"
18
19print(f"Pyton: {python_name}")

get() vs []:

  • dict[key]
    - rzuca KeyError jeśli brak klucza
  • dict.get(key)
    - zwraca None jeśli brak klucza
  • dict.get(key, default)
    - zwraca default jeśli brak klucza

Dodawanie i modyfikowanie

1catalog = {
2    "Python regius": {"długość": 1.5, "habitat": "jungle"}
3}
4
5# Dodawanie nowego wpisu
6catalog["Panthera leo"] = {"długość": 2.5, "habitat": "savanna"}
7
8# Modyfikowanie istniejącego
9catalog["Python regius"]["długość"] = 1.8
10
11# Dodawanie przez update() - słownik lub pary klucz-wartość
12catalog.update({"Loxodonta africana": {"długość": 4.0, "habitat": "savanna"}})
13catalog.update(discovered_by="Darwin", year=2024)
14
15print(catalog)

Usuwanie elementów

1species = {
2    "Python": "Pyton",
3    "Leo": "Lew",
4    "Elephas": "Słoń",
5    "Giraffa": "Żyrafa"
6}
7
8# del - usuń przez klucz
9del species["Giraffa"]
10
11# pop() - usuń i zwróć wartość
12leo_value = species.pop("Leo")  # "Lew"
13print(leo_value)
14
15# pop() z defaultem (jeśli nie ma klucza)
16dino = species.pop("T-Rex", "Nie znaleziono")  # "Nie znaleziono"
17
18# popitem() - usuń i zwróć OSTATNIĄ parę (Python 3.7+)
19last_item = species.popitem()  # ("Elephas", "Słoń")
20
21# clear() - wyczyść cały słownik
22species.clear()
23print(species)  # {}

Sprawdzanie obecności klucza

1catalog = {
2    "Python regius": "Pyton",
3    "Panthera leo": "Lew"
4}
5
6# in - sprawdź czy klucz istnieje
7if "Python regius" in catalog:
8    print("Pyton jest w katalogu!")
9
10if "T-Rex" not in catalog:
11    print("T-Rex nie ma w katalogu")
12
13# Uwaga: 'in' sprawdza KLUCZE, nie wartości!
14print("Pyton" in catalog)  # False (to wartość, nie klucz!)

Iteracja przez słownik

1species = {
2    "Python regius": "Pyton królewski",
3    "Panthera leo": "Lew",
4    "Loxodonta africana": "Słoń afrykański"
5}
6
7# Iteracja przez klucze (default)
8for species_name in species:
9    print(species_name)
10
11# Jawnie przez klucze - keys()
12for key in species.keys():
13    print(key)
14
15# Iteracja przez wartości - values()
16for name_pl in species.values():
17    print(name_pl)
18
19# Iteracja przez pary klucz-wartość - items() (najczęściej!)
20for species_name, name_pl in species.items():
21    print(f"{species_name}: {name_pl}")
22
23# Enumerate dla numerowania
24for i, (key, value) in enumerate(species.items(), start=1):
25    print(f"{i}. {key} -> {value}")

Metody słowników

keys(), values(), items()

1catalog = {
2    "Python": {"habitat": "jungle", "size": 1.5},
3    "Leo": {"habitat": "savanna", "size": 2.5}
4}
5
6# Wszystkie klucze
7all_keys = catalog.keys()  # dict_keys(['Python', 'Leo'])
8keys_list = list(catalog.keys())  # Lista: ['Python', 'Leo']
9
10# Wszystkie wartości
11all_values = catalog.values()  # dict_values([{...}, {...}])
12
13# Wszystkie pary
14all_items = catalog.items()  # dict_pairs([('Python', {...}), ('Leo', {...})])
15
16# Konwersja na listy
17keys = list(catalog.keys())
18values = list(catalog.values())
19items = list(catalog.items())

get() - bezpieczny dostęp

1species = {"Python": "Pyton", "Leo": "Lew"}
2
3# get(key) - None jeśli brak
4result = species.get("Python")  # "Pyton"
5result = species.get("T-Rex")   # None
6
7# get(key, default) - własny default
8result = species.get("T-Rex", "Nie znaleziono!")  # "Nie znaleziono!"

setdefault() - zwróć wartość LUB ustaw domyślną

1catalog = {"Python": {"count": 5}}
2
3# Jeśli klucz istnieje - zwróć wartość
4python_data = catalog.setdefault("Python", {"count": 0})
5print(python_data)  # {"count": 5}
6
7# Jeśli klucz NIE istnieje - dodaj z defaultem
8leo_data = catalog.setdefault("Leo", {"count": 0})
9print(leo_data)  # {"count": 0}
10print(catalog)   # {'Python': {...}, 'Leo': {'count': 0}}

update() - aktualizuj/scal słowniki

1catalog1 = {"Python": "Pyton", "Leo": "Lew"}
2catalog2 = {"Elephas": "Słoń", "Giraffa": "Żyrafa"}
3new_data = {"Python": "Pyton królewski"}  # Nadpisze
4
5# Aktualizacja słownikiem
6catalog1.update(catalog2)
7print(catalog1)  # {'Python': 'Pyton', 'Leo': 'Lew', 'Elephas': 'Słoń', 'Giraffa': 'Żyrafa'}
8
9# Aktualizacja parami klucz=wartość
10catalog1.update(discovered_by="Darwin", year=2024)

copy() - kopiowanie słownika

1# UWAGA - to NIE kopiuje!
2original = {"A": 1, "B": 2}
3reference = original  # Ta sama referencja!
4reference["A"] = 999
5print(original)  # {'A': 999, 'B': 2} - zmienione!
6
7# Prawidłowe kopiowanie
8original = {"A": 1, "B": 2}
9copy1 = original.copy()  # Płytka kopia
10copy2 = dict(original)   # Alternatywa
11
12copy1["A"] = 999
13print(original)  # {'A': 1, 'B': 2} - bez zmian!
14
15# Głęboka kopia (dla zagnieżdżonych słowników)
16import copy
17nested = {"team": {"leader": "Darwin", "size": 5}}
18deep = copy.deepcopy(nested)
19deep["team"]["leader"] = "Alex"
20print(nested)  # {'team': {'leader': 'Darwin', 'size': 5}} - bez zmian!

Dictionary comprehensions

Podobnie jak list comprehensions, możesz tworzyć słowniki w jednej linii!

1# Tradycyjny sposób
2squares = {}
3for x in range(1, 6):
4    squares[x] = x ** 2
5# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
6
7# Dict comprehension!
8squares = {x: x ** 2 for x in range(1, 6)}
9# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
10
11# Z warunkiem
12even_squares = {x: x ** 2 for x in range(1, 11) if x % 2 == 0}
13# {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
14
15# Zamiana kluczy i wartości
16species = {"Python": "Pyton", "Leo": "Lew"}
17reversed_dict = {value: key for key, value in species.items()}
18# {"Pyton": "Python", "Lew": "Leo"}
19
20# Z dwóch list
21names = ["Python", "Leo", "Elephas"]
22polish_names = ["Pyton", "Lew", "Słoń"]
23catalog = {name: pl_name for name, pl_name in zip(names, polish_names)}

Zagnieżdżone słowniki

Słowniki mogą zawierać inne słowniki - idealne dla złożonych danych!

1# Katalog ekspedycji z szczegółami każdego gatunku
2species_database = {
3    "Python regius": {
4        "nazwa_pl": "Pyton królewski",
5        "charakterystyka": {
6            "długość_m": 1.5,
7            "waga_kg": 2.5,
8            "siedlisko": "jungle"
9        },
10        "status": "discovered",
11        "odkrywca": "Darwin",
12        "data": "2024-01-15"
13    },
14    "Panthera leo": {
15        "nazwa_pl": "Lew",
16        "charakterystyka": {
17            "długość_m": 2.5,
18            "waga_kg": 190,
19            "siedlisko": "savanna"
20        },
21        "status": "observed",
22        "odkrywca": "Team B"
23    }
24}
25
26# Dostęp do zagnieżdżonych wartości
27python_length = species_database["Python regius"]["charakterystyka"]["długość_m"]
28print(f"Długość pytona: {python_length}m")
29
30# Bezpieczny dostęp do głęboko zagnieżdżonych wartości
31leo_weight = species_database.get("Panthera leo", {}).get("charakterystyka", {}).get("waga_kg", "Brak danych")
32print(f"Waga lwa: {leo_weight}kg")

Operacje na słownikach

1# Długość (liczba par klucz-wartość)
2species = {"Python": "Pyton", "Leo": "Lew", "Elephas": "Słoń"}
3count = len(species)  # 3
4
5# Scalanie słowników (Python 3.9+)
6dict1 = {"A": 1, "B": 2}
7dict2 = {"C": 3, "D": 4}
8merged = dict1 | dict2  # {'A': 1, 'B': 2, 'C': 3, 'D': 4}
9
10# Scalanie z nadpisaniem (Python 3.9+)
11dict1 = {"A": 1, "B": 2}
12dict2 = {"B": 999, "C": 3}
13merged = dict1 | dict2  # {'A': 1, 'B': 999, 'C': 3} - B nadpisane!
14
15# Operator |= (modyfikuje pierwszy słownik)
16dict1 |= dict2  # dict1 teraz zawiera scalone dane
17
18# Min/Max kluczy
19species = {"Python": 5, "Leo": 12, "Elephas": 3}
20max_key = max(species)  # "Python" (alfabetycznie)
21max_value = max(species.values())  # 12
22max_by_value = max(species, key=species.get)  # "Leo" (największa wartość)

Sortowanie słowników

1species_count = {
2    "Python": 5,
3    "Leo": 12,
4    "Elephas": 3,
5    "Giraffa": 8
6}
7
8# Sortowanie po kluczach
9sorted_by_key = dict(sorted(species_count.items()))
10# {'Elephas': 3, 'Giraffa': 8, 'Leo': 12, 'Python': 5}
11
12# Sortowanie po wartościach
13sorted_by_value = dict(sorted(species_count.items(), key=lambda x: x[1]))
14# {'Elephas': 3, 'Python': 5, 'Giraffa': 8, 'Leo': 12}
15
16# Sortowanie malejąco po wartościach
17sorted_desc = dict(sorted(species_count.items(), key=lambda x: x[1], reverse=True))
18# {'Leo': 12, 'Giraffa': 8, 'Python': 5, 'Elephas': 3}

Praktyczny przykład - System katalogowania

1# System katalogowania odkrytych gatunków
2
3species_catalog = {}
4
5def add_species(name, name_pl, habitat, dangerous, notes=""):
6    """Dodaj gatunek do katalogu"""
7    species_catalog[name] = {
8        "nazwa_pl": name_pl,
9        "habitat": habitat,
10        "niebezpieczny": dangerous,
11        "notatki": notes,
12        "data_odkrycia": "2024-11-24"  # Przykładowa data
13    }
14    print(f"✓ Dodano: {name}")
15
16def show_catalog():
17    """Wyświetl cały katalog"""
18    if not species_catalog:
19        print("Katalog jest pusty!")
20        return
21
22    print(f"\n=== KATALOG GATUNKÓW ({len(species_catalog)} wpisów) ===")
23    for name, data in species_catalog.items():
24        danger = "⚠️ NIEBEZPIECZNY" if data["niebezpieczny"] else "✓ Bezpieczny"
25        print(f"\n{name} ({data['nazwa_pl']})")
26        print(f"  Siedlisko: {data['habitat']}")
27        print(f"  Status: {danger}")
28        if data["notatki"]:
29            print(f"  Notatki: {data['notatki']}")
30
31def search_species(name):
32    """Szukaj gatunku po nazwie"""
33    if name in species_catalog:
34        data = species_catalog[name]
35        print(f"\n✓ Znaleziono: {name}")
36        print(f"Nazwa polska: {data['nazwa_pl']}")
37        print(f"Siedlisko: {data['habitat']}")
38        print(f"Niebezpieczny: {'Tak' if data['niebezpieczny'] else 'Nie'}")
39    else:
40        print(f"\n✗ Nie znaleziono: {name}")
41
42def filter_by_habitat(habitat):
43    """Filtruj gatunki po siedlisku"""
44    filtered = {name: data for name, data in species_catalog.items()
45                if data["habitat"] == habitat}
46
47    print(f"\nGatunki w siedlisku '{habitat}': {len(filtered)}")
48    for name in filtered:
49        print(f"  - {name}")
50
51# Użycie systemu
52add_species("Python regius", "Pyton królewski", "jungle", False, "Spokojny gatunek")
53add_species("Panthera leo", "Lew", "savanna", True, "Obserwować z daleka!")
54add_species("Gorilla gorilla", "Goryl", "jungle", False)
55
56show_catalog()
57search_species("Python regius")
58filter_by_habitat("jungle")

Lista vs Słownik - kiedy użyć?

Użyj listy gdy:

  • ✅ Kolejność jest ważna
  • ✅ Potrzebujesz dostępu przez indeks numeryczny
  • ✅ Możesz mieć duplikaty
  • ✅ Prosty zbiór wartości

Użyj słownika gdy:

  • ✅ Potrzebujesz szybkiego dostępu przez klucz
  • ✅ Każdy element ma swoją unikalną etykietę
  • ✅ Dane mają strukturę klucz-wartość
  • ✅ Chcesz łatwo sprawdzić czy element istnieje

Zadanie praktyczne

Stwórz "Expedition Equipment Manager":

  1. Słownik ekwipunku (nazwa: ilość)
  2. Dodawanie/usuwanie przedmiotów
  3. Zwiększanie/zmniejszanie ilości
  4. Wyświetlanie całego ekwipunku
  5. Sprawdzanie czy przedmiot jest dostępny

Podsumowanie

W tej lekcji nauczyłeś/aś się:

  • ✅ Czym są słowniki (pary klucz-wartość)
  • ✅ Tworzenie i dostęp do słowników
  • ✅ Dodawanie, modyfikowanie, usuwanie elementów
  • ✅ Metod: keys(), values(), items(), get(), update(), setdefault()
  • ✅ Dictionary comprehensions
  • ✅ Zagnieżdżonych słowników
  • ✅ Iteracji przez słowniki
  • ✅ Sortowania i operacji na słownikach

Checkpoint

Przed przejściem dalej:

  • [ ] Rozumiesz różnicę między listą a słownikiem
  • [ ] Potrafisz użyć get() zamiast []
  • [ ] Znasz items(), keys(), values()
  • [ ] Potrafisz iterować przez słownik
  • [ ] Umiesz tworzyć dict comprehensions
  • [ ] Rozumiesz zagnieżdżone słowniki

W następnej lekcji Darwin pokaże Ci comprehensions - elegancki sposób tworzenia kolekcji! 🚀

Przejdź do CodeWorlds