Pary klucz–wartość, tworzenie, metody, iterowanie, słowniki zagnieżdżone.
Słownik (dict) to kolekcja par
klucz–wartość. Pozwala szybko znaleźć wartość na
podstawie klucza — jak w prawdziwym słowniku: szukasz słowa
(klucz), znajdujesz definicję (wartość).
{klucz: wartość, ...}
TypeError: unhashable type: 'list'. Wartości
mogą być wszystkim, łącznie z listami.
# Słownik z literałem
uczen = {
"imie": "Kasia",
"wiek": 17,
"oceny": [4, 5, 3, 5],
"aktywny": True
}
# Pusty słownik
pusty = {}
pusty2 = dict()
# Ze słowa kluczowego dict()
osoba = dict(imie="Marek", wiek=20)
# Z listy par
pary = [("a", 1), ("b", 2), ("c", 3)]
d = dict(pary)
print(d) # {'a': 1, 'b': 2, 'c': 3}
# Dict comprehension
kwadraty = {x: x**2 for x in range(1, 6)}
print(kwadraty) # {1:1, 2:4, 3:9, 4:16, 5:25}
Do wartości w słowniku odwołujesz się przez klucz w nawiasach
kwadratowych. Możesz też użyć metody get() —
bezpieczniejszej, bo nie powoduje błędu gdy klucz nie istnieje.
| Operacja | Składnia | Uwaga |
|---|---|---|
| Odczyt | d[klucz] |
KeyError gdy brak klucza |
| Bezpieczny odczyt | d.get(klucz) |
zwraca None gdy brak |
| Odczyt z domyślną | d.get(klucz, domyślna) |
zwraca domyślną gdy brak |
| Dodanie/zmiana | d[klucz] = wartość |
nadpisuje jeśli istnieje |
| Usunięcie | del d[klucz] |
KeyError gdy brak |
| Czy klucz istnieje | klucz in d |
True/False |
get(). Unikniesz KeyError który przerywa
program.
kontakt = {
"imie": "Zofia",
"email": "zofia@mail.pl",
"telefon": "123456789"
}
# Odczyt
print(kontakt["imie"]) # Zofia
print(kontakt.get("email")) # zofia@mail.pl
print(kontakt.get("wiek")) # None — bez błędu!
print(kontakt.get("wiek", 0)) # 0 — wartość domyślna
# Sprawdzenie istnienia klucza
if "telefon" in kontakt:
print(kontakt["telefon"]) # 123456789
# Dodanie nowego klucza
kontakt["miasto"] = "Kraków"
print(kontakt)
# Zmiana wartości
kontakt["email"] = "z.nowy@mail.pl"
# Usunięcie
del kontakt["telefon"]
print("telefon" in kontakt) # False
| Metoda | Działanie | Zwraca |
|---|---|---|
keys() |
wszystkie klucze | dict_keys |
values() |
wszystkie wartości | dict_values |
items() |
pary (klucz, wartość) | dict_items |
get(k, d) |
wartość lub domyślna | wartość / None |
pop(k) |
usuwa i zwraca wartość klucza k | wartość |
popitem() |
usuwa i zwraca ostatnią parę | krotka |
update(d2) |
dodaje/nadpisuje pary z d2 | None |
setdefault(k, v) |
zwraca wartość k lub ustawia v | wartość |
clear() |
usuwa wszystkie pary | None |
copy() |
płytka kopia słownika | dict |
list():
list(d.keys()).
oceny = {"Kasia": 5, "Marek": 4, "Zofia": 3}
# Widoki
print(list(oceny.keys())) # ['Kasia', 'Marek', 'Zofia']
print(list(oceny.values())) # [5, 4, 3]
print(list(oceny.items()))
# [('Kasia', 5), ('Marek', 4), ('Zofia', 3)]
# pop — usuń i zwróć
o = oceny.pop("Marek")
print(o) # 4
print(oceny) # {'Kasia': 5, 'Zofia': 3}
# update — dodaj/nadpisz
nowe = {"Piotr": 5, "Kasia": 6}
oceny.update(nowe)
print(oceny)
# {'Kasia': 6, 'Zofia': 3, 'Piotr': 5}
# setdefault — ustaw jeśli brak
oceny.setdefault("Ola", 4) # dodaje "Ola": 4
oceny.setdefault("Kasia", 1) # Kasia już jest — bez zmiany
print(oceny["Ola"]) # 4
print(oceny["Kasia"]) # 6
Słownik możesz przejść pętlą for na kilka sposobów.
Najczęściej używane to iterowanie po parach przez
items().
for k in slownik — iteruje po kluczachfor k in slownik.keys() — to samo, bardziej jawnie
for v in slownik.values() — iteruje po wartościach
for k, v in slownik.items() — klucz i wartość
jednocześnie
RuntimeError. Iteruj po
kopii: for k in list(d.keys()).
punkty = {
"Kasia": 87,
"Marek": 92,
"Zofia": 74,
"Piotr": 88
}
# Po kluczach
for imie in punkty:
print(imie, end=" ")
# Kasia Marek Zofia Piotr
# Po wartościach
for p in punkty.values():
print(p, end=" ")
# 87 92 74 88
# Po parach — najczęściej używane
for imie, p in punkty.items():
print(f"{imie}: {p} pkt")
# Znalezienie najlepszego
najlepszy = max(punkty, key=punkty.get)
print(f"Najlepszy: {najlepszy} ({punkty[najlepszy]} pkt)")
# Filtrowanie — tylko > 85
swietni = {k: v for k, v in punkty.items() if v > 85}
print(swietni)
# {'Kasia': 87, 'Marek': 92, 'Piotr': 88}
Analogicznie do list comprehension — zwięzły sposób tworzenia słowników.
{klucz: wartość for x in sekwencja}
{k: v for k, v in d.items() if warunek}
{v: k for k, v in d.items()}
{k: f(v) for k, v in d.items()}
{v: k for k, v in d.items()} zamienia klucze z
wartościami. Działa poprawnie tylko gdy wartości są unikalne —
inaczej niektóre klucze zostaną nadpisane.
# Kwadraty liczb
kwadraty = {x: x**2 for x in range(1, 8)}
print(kwadraty)
# {1:1, 2:4, 3:9, 4:16, 5:25, 6:36, 7:49}
# Filtrowanie par
ceny = {"jabłko": 2.5, "banan": 1.2, "mango": 8.9}
tanie = {k: v for k, v in ceny.items() if v < 5}
print(tanie) # {'jabłko': 2.5, 'banan': 1.2}
# Transformacja wartości — zaokrąglenie
zaokr = {k: round(v) for k, v in ceny.items()}
print(zaokr) # {'jabłko': 2, 'banan': 1, 'mango': 9}
# Odwrócenie słownika
dni = {"pon": 1, "wt": 2, "sr": 3, "czw": 4}
odwr = {v: k for k, v in dni.items()}
print(odwr) # {1:'pon', 2:'wt', 3:'sr', 4:'czw'}
# Z listy — zliczanie wystąpień liter
tekst = "mississippi"
zlicz = {l: tekst.count(l) for l in set(tekst)}
print(zlicz) # {'m':1, 'i':4, 's':4, 'p':2}
Wartością w słowniku może być inny słownik. To pozwala modelować złożone struktury danych — np. baza uczniów, konfiguracja programu.
d[klucz1][klucz2]d.get(k1, {}).get(k2)d[k1][k2] = nowa_wartośćuczniowie = {
"u001": {
"imie": "Kasia",
"klasa": "3A",
"oceny": [4, 5, 5, 3]
},
"u002": {
"imie": "Marek",
"klasa": "3B",
"oceny": [3, 4, 2, 5]
}
}
# Dostęp do zagnieżdżonych danych
print(uczniowie["u001"]["imie"]) # Kasia
print(uczniowie["u002"]["oceny"]) # [3, 4, 2, 5]
# Modyfikacja
uczniowie["u001"]["oceny"].append(4)
# Iterowanie po wszystkich uczniach
for uid, dane in uczniowie.items():
sr = sum(dane["oceny"]) / len(dane["oceny"])
print(f"{uid} | {dane['imie']:8} | "
f"{dane['klasa']} | avg: {sr:.2f}")
# Dodanie nowego ucznia
uczniowie["u003"] = {
"imie": "Zofia",
"klasa": "3A",
"oceny": [5, 5, 4, 5]
}
Wczytaj zdanie od użytkownika. Policz ile razy każde słowo wystąpiło w zdaniu (bez rozróżniania wielkich/małych liter). Wypisz słowa i ich liczby posortowane od najczęstszego.
zdanie = input("Wpisz zdanie: ").lower()
slowa = zdanie.split()
czestosci = {}
for slowo in slowa:
czestosci[slowo] = czestosci.get(slowo, 0) + 1
posortowane = sorted(czestosci.items(),
key=lambda x: x[1],
reverse=True)
print("\nCzęstości słów:")
for slowo, ile in posortowane:
print(f" {slowo:<15} {ile}x")
czestosci.get(slowo, 0) + 1 — jeśli słowo już
jest w słowniku, pobierz jego licznik i dodaj 1. Jeśli nie ma
— get zwraca 0, dodajemy 1. Elegancki wzorzec
liczenia bez sprawdzania if slowo in.
sorted(czestosci.items(), key=lambda x: x[1],
reverse=True)
— sortujemy pary (słowo, licznik) po drugim elemencie
(x[1]) malejąco.
Masz słownik z cenami produktów. Wczytuj od użytkownika nazwę produktu i ilość — dodawaj do koszyka. Wpisanie "koniec" kończy zakupy. Wypisz rachunek: każdy produkt, jego cenę, ilość i koszt, oraz łączną sumę.
cennik = {
"jabłko": 1.50,
"banan": 0.80,
"chleb": 3.20,
"mleko": 2.90,
"masło": 6.50
}
koszyk = {} # {produkt: ilosc}
while True:
produkt = input("Produkt (lub 'koniec'): ").lower()
if produkt == "koniec":
break
if produkt not in cennik:
print(f"Nie ma '{produkt}' w ofercie.")
continue
ilosc = int(input(f"Ile sztuk? "))
koszyk[produkt] = koszyk.get(produkt, 0) + ilosc
print("\n--- RACHUNEK ---")
suma = 0
for produkt, ilosc in koszyk.items():
koszt = cennik[produkt] * ilosc
suma += koszt
print(f"{produkt:<10} {ilosc:>3} szt. × "
f"{cennik[produkt]:.2f} = {koszt:.2f} zł")
print(f"{'SUMA':<10} {suma:>18.2f} zł")
if produkt not in cennik — zanim cokolwiek
zrobimy, upewniamy się że produkt jest w ofercie. Bez tego —
KeyError.
koszyk.get(produkt, 0) + ilosc — jeśli produkt
już jest w koszyku (kupiony wcześniej), dodajemy do
istniejącej ilości zamiast nadpisywać.
:<10 wyrównuje do lewej,
:>3 do prawej — kolumny są równe niezależnie
od długości nazwy produktu.
Masz listę słowników z uczniami (imię i klasa). Grupuj uczniów według klasy — wynikiem ma być słownik gdzie kluczem jest klasa, a wartością lista imion uczniów. Wypisz każdą klasę z posortowaną listą imion.
uczniowie = [
{"imie": "Kasia", "klasa": "3A"},
{"imie": "Marek", "klasa": "3B"},
{"imie": "Zofia", "klasa": "3A"},
{"imie": "Piotr", "klasa": "3C"},
{"imie": "Ola", "klasa": "3B"},
{"imie": "Tomek", "klasa": "3A"},
{"imie": "Ania", "klasa": "3C"},
]
klasy = {}
for u in uczniowie:
klasa = u["klasa"]
imie = u["imie"]
if klasa not in klasy:
klasy[klasa] = []
klasy[klasa].append(imie)
for klasa in sorted(klasy):
lista = sorted(klasy[klasa])
print(f"{klasa}: {', '.join(lista)}")
klasy.setdefault(klasa, []).append(imie) — to
jedno wyrażenie zastępuje blok if.
setdefault zwraca istniejącą lub nowo utworzoną
wartość.
sorted(klasy) — sortuje klucze słownika (nazwy
klas) alfabetycznie. sorted(klasy[klasa]) —
sortuje imiona w każdej klasie.
', '.join(lista) łączy elementy listy w tekst
rozdzielony przecinkami. Czytelniejsze niż drukowanie całej
listy z nawiasami.
Słowniki są wszechstronne — ćwicz różne wzorce: zliczanie, grupowanie, odwracanie, filtrowanie.
Tłumacz PL–EN
Stwórz słownik 10 słów polsko-angielskich. Wczytuj słowa od użytkownika i tłumacz je. Jeśli słowa nie ma — wypisz komunikat. Wpisanie "quit" kończy program.
while True, get() z domyślną
wartością
Inwentaryzacja
Wczytuj pary: nazwa produktu i ilość. Jeśli produkt już istnieje — dodaj ilość. Wypisz końcowy stan magazynu posortowany alfabetycznie.
get(k, 0) + ilosc,
sorted(d.items())
Anagram
Napisz funkcję sprawdzającą czy dwa słowa są anagramami (zawierają te same litery w tej samej liczbie). Użyj słownika do zliczenia liter.
{litera: count} i
porównaj je
Ranking punktowy
Wczytuj imię i punkty gracza. Jeśli gracz już istnieje — sumuj punkty. Na koniec wypisz top 3 graczy z największą liczbą punktów.
sorted(d.items(), key=lambda x: x[1], reverse=True)[:3]
Dict comprehension — zamiana
Masz słownik cen produktów w złotówkach. Używając dict comprehension utwórz nowy słownik z cenami w euro (kurs: 1 EUR = 4.25 PLN), zaokrąglonymi do 2 miejsc.
{k: round(v/4.25, 2) for k, v in ...}
Baza uczniów
Zbuduj słownik zagnieżdżony uczniów (id → dane). Zaimplementuj: dodaj ucznia, usuń ucznia, wypisz wszystkich posortowanych po nazwisku, oblicz średnią dla każdego.
sorted(d.items(), key=lambda x: x[1]['nazwisko'])