Historia pytania:
Słowniki (dict) — jeden z podstawowych typów danych w Pythonie, reprezentujący strukturę „klucz-wartość”. Słowniki pojawiły się w pierwszym Pythonie, ale ich wewnętrzna implementacja i cechy zachowania były stale doskonalone (na przykład w Pythonie 3.7 gwarantowany jest porządek wstawiania).
Problem:
Zrozumienie działania słownika jest niezbędne do efektywnego pisania kodu. Bez znajomości szczegółów pojawiają się błędy przy używaniu typów mutowalnych jako kluczy, podczas kopiowania zagnieżdżonych słowników, a także przy niestandardowych operacjach.
Rozwiązanie:
Słownik jest zrealizowany jako tablica haszująca, klucze muszą być koniecznie haszowalne (niemutowalne). Dostęp do wartości za pomocą klucza działa blisko O(1), ale w pewnych warunkach występują szczególności — na przykład przy kolizjach lub pracy z dużymi ilościami danych.
Przykład kodu:
person = {'name': 'Alice', 'age': 30} person['city'] = 'Moscow' print(person['name']) # Alice
Kluczowe cechy:
Czy można użyć listy (list) jako klucza w dict?
Nie, listy są mutowalne i nie są haszowalne. Próba użycia listy spowoduje błąd.
d = {} d[[1, 2, 3]] = 'value' # TypeError: unhashable type: 'list'
Co się stanie, jeśli jako klucza użyjesz dwóch krotek o tej samej zawartości?
Jeśli obie krotki zawierają te same dane i same są niemutowalne, są uważane za równe, a klucze w słowniku będą się pokrywać:
t1 = (1, 2) t2 = (1, 2) d = {t1: 'a'} print(d[t2]) # 'a'
Czy porządek przeszukiwania elementów słownika zmieni się przy kopiowaniu?
W wersjach Python 3.7+ porządek zostanie zachowany. W starszych — porządek przeszukiwania nie jest gwarantowany.
d1 = {'a': 1, 'b': 2} d2 = dict(d1) print(list(d2)) # ['a', 'b']
dict.get() bez sprawdzania na None może prowadzić do nieoczekiwanych błędów, jeśli wartość == None.Programista przechowuje listy jako klucze, błędnie sądząc, że tuple i list w Pythonie są równoważne jako klucze. Otrzymuje wyjątki takie jak „unhashable type”.
Zalety:
Można szybko spróbować czegoś „na kolanie”, używać dowolnych struktur.
Wady:
Błędy w czasie wykonywania, błędy przy przetwarzaniu danych.
Używane są tylko niemutowalne (haszowalne) obiekty jako klucze, krotki są przemyślane tak, aby nie zawierały elementów mutowalnych.
Zalety:
Szybkość wyszukiwania po kluczu, niezawodność struktury, łatwe przetwarzanie i kopiowanie.
Wady:
Jeśli dane są skomplikowane, wymagana jest dodatkowa obróbka, aby przekształcić strukturę w formę niemutowalną (na przykład, serializacja wewnątrz tuple).