Jak i kiedy należy używać Defaultdict w Pythonie?

W tym samouczku dowiesz się, jak używać defaultdict z modułu kolekcji Pythona — aby lepiej radzić sobie z KeyErrors — podczas pracy ze słownikami Pythona.

W Pythonie słownik jest potężną wbudowaną strukturą danych, która przechowuje dane w parach klucz-wartość. Użyjesz klawiszy, aby wejść do słownika i uzyskać dostęp do wartości.

Jeśli jednak w skrypcie Pythona znajduje się wiele słowników, które są modyfikowane podczas wykonywania kodu, często natrafisz na KeyErrors. Istnieje kilka różnych sposobów, w jaki możesz sobie z nimi poradzić.

W tym samouczku dowiesz się:

  • Czym są KeyErrors i dlaczego powstają
  • Jak radzić sobie z KeyErrors?
  • Jak używać defaultdict Pythona, podklasy, która dziedziczy z wbudowanej klasy dict, aby lepiej obsługiwać brakujące klucze

Zaczynajmy!

Czym są KeyErrors w Pythonie?

Podczas definiowania słownika Pythona należy zadbać o to, aby:

  • Klucze powinny być niepowtarzalne – bez żadnych powtórzeń.
  • Używając istniejącego elementu iteracyjnego jako kluczy słownika, powinieneś preferować użycie niezmiennej kolekcji, takiej jak krotka.

Tak więc klucz jest ważny tylko wtedy, gdy jest obecny w słowniku; w przeciwnym razie prowadzi do KeyErrors.

Rozważmy następujący słownik books_authors, w którym klucze są nazwami książek, a wartościami są nazwiska autorów.

Możesz kodować wraz z tym samouczkiem w Pythonie REPL.

books_authors = {
    'Deep Work':'Cal Newport',
    'Hyperfocus':'Chris Bailey',
    'Pivot':'Jenny Blake',
    'The Happiness Equation':'Neil Pasricha'
}

Możesz użyć klucza (nazwy książki), aby uzyskać dostęp do nazwiska autora.

books_authors['Hyperfocus']
'Chris Bailey'

Aby uzyskać dostęp do wszystkich par klucz-wartość w słowniku, możesz wywołać metodę items() obiektu słownika, jak pokazano poniżej:

for book,author in books_authors.items():
  print(f"'{book}' by {author}")
'Deep Work' by Cal Newport
'Hyperfocus' by Chris Bailey
'Pivot' by Jenny Blake
'The Happiness Equation' by Neil Pasricha

Jeśli spróbujesz uzyskać dostęp do wartości klucza, którego nie ma w słowniku, interpreter Pythona zgłosi KeyError. Natrafiamy na KeyError, gdy próbujemy uzyskać dostęp do wartości kluczy, które nie istnieją, a mianowicie „Grit” i „nieistniejący klucz”.

books_authors['Grit']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-6-e1a4486f5ced> in <module>
----> 1 books_authors['Grit']

KeyError: 'Grit'
books_authors['non-existent-key']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-7-a3efd56f69e5> in <module>
----> 1 books_authors['non-existent-key']

KeyError: 'non-existent-key'

Więc jak radzisz sobie z KeyErrors w Pythonie?

Jest na to kilka sposobów, których nauczymy się w następnej sekcji.

Jak radzić sobie z keyErrors w Pythonie?

Nauczmy się, jak radzić sobie z KeyErrors za pomocą:

  • Instrukcje warunkowe if-else
  • Wypróbuj z wyjątkiem bloków
  • Metoda słownikowa .get()

#1. Korzystanie z instrukcji warunkowych if-else

Jednym z najprostszych sposobów obsługi błędów KeyErrors w Pythonie jest użycie instrukcji warunkowych if-else.

W Pythonie instrukcje if-else mają następującą ogólną składnię:

 if condition:
 	# do this 
 else:
    # do something else 
  • Jeśli warunek ma wartość True, instrukcje w treści if zostaną wykonane, a
  • Jeśli warunek ma wartość False, wykonywane są instrukcje w treści else.

W tym przykładzie warunkiem jest sprawdzenie, czy klucz jest obecny w słowniku.

Jeśli klucz jest obecny w słowniku, operator in zwróci True, a jeśli body zostanie wykonane, wypisze odpowiednią wartość.

key = 'The Happiness Equation'
if key in books_authors:
  print(books_authors[key])
else:
  print('Sorry, this key does not exist!')

# Output
# Neil Pasricha

Jeśli klucz nie występuje w słowniku, operator in zwraca False i wykonywane jest ciało else. Wyświetla komunikat, że nie ma klucza.

key = 'non-existent-key'
if key in books_authors:
  print(books_authors[key])
else:
  print('Sorry, this key does not exist!')

# Output
# Sorry, this key does not exist!

#2. Korzystanie z instrukcji Try-Except

Inną powszechną metodą obsługi KeyError jest użycie instrukcji try-except w Pythonie.

Przeczytaj następujący blok kodu:

key = 'non-existent-key'
try:
  print(books_authors[key])
except KeyError:
  print('Sorry, this key does not exist!')
  • Blok try próbuje pobrać wartość odpowiadającą podanemu kluczowi.
  • Jeśli klucz nie jest obecny, interpreter zgłasza KeyError, który jest obsługiwany jako wyjątek w bloku z wyjątkiem.

#3. Korzystanie z metody .get()

W Pythonie możesz użyć wbudowanej metody słownikowej .get() do obsługi brakujących kluczy.

Ogólna składnia metody get() to dict.get(klucz,wartość_domyślna), gdzie dict jest poprawnym obiektem słownika w Pythonie.

– Jeśli klucz jest obecny w słowniku, metoda get() zwraca wartość.
– W przeciwnym razie zwraca wartość domyślną.

W tym przykładzie klucze to lista kluczy, do których wartości chcielibyśmy uzyskać dostęp. Przechodzimy przez listę kluczy, aby pobrać odpowiednie wartości ze słownika books_authors.

Tutaj użyliśmy metody .get() z wartością domyślną „Nie istnieje”.

keys = ['Grit','Hyperfocus','Make Time','Deep Work']
for key in keys:
  print(books_authors.get(key,'Does not exist'))

W powyższym kodzie:

  • W przypadku kluczy znajdujących się w słowniku books_authors metoda .get() zwraca odpowiednie wartości.
  • Gdy klucze nie istnieją, w tym przypadku „Grit” i „Make Time”, metoda .get() zwraca domyślną wartość „Nie istnieje”.
# Output

Does not exist
Chris Bailey
Does not exist
Cal Newport

Wszystkie powyższe metody pomagają nam w obsłudze kluczowych błędów. Są one jednak gadatliwe i wymagają od nas wyraźnego obsłużenia brakujących kluczy. Możesz uprościć ten proces, używając domyślnego słownika zamiast zwykłego słownika.

Defaultdict w Pythonie

Defaultdict jest podklasą klasy Dictionary (dict). Dziedziczy więc zachowanie słownika Pythona. Ponadto natywnie obsługuje również brakujące klucze.

Defaultdict to typ danych kontenera wbudowany w standardową bibliotekę Pythona — wewnątrz modułu collections.

Musisz więc zaimportować go do swojego środowiska pracy:

from collections import defaultdict

Oto ogólna składnia użycia defaultdict:

defaultdict(default_factory)

Możesz określić wywoływalne, takie jak int, float lub list jako atrybut default_factory. Jeśli nie podasz wartości dla default_factory, wartość domyślna to Brak.

Gdy klucz, którego szukasz, nie jest obecny, wywoływana jest metoda __missing__() i wywnioskuje ona domyślną wartość z default_factory. Następnie zwraca tę wartość domyślną.

W podsumowaniu:

  • W Pythonie defaultdict zwraca wartość domyślną, gdy klucz nie jest obecny.
  • Dodaje również tę parę klucz-wartość domyślna do słownika, który można następnie modyfikować.

Przykłady defaultdict w Pythonie

Następnie napiszemy kilka przykładów, aby zrozumieć, jak działa defaultdict Pythona.

Defaultdict w Pythonie z domyślną wartością całkowitą

Najpierw zaimportuj defaultdict z modułu kolekcji.

from collections import defaultdict
import random

Stwórzmy domyślne ceny.

prices = defaultdict(int)

Teraz wypełniamy słownik cen, używając jako kluczy pozycji z listy owoców. I losowo próbkujemy wartości z cennika, aby uzyskać wartości.

price_list = [10,23,12,19,5]
fruits = ['apple','strawberry','pomegranate','blueberry']

for fruit in fruits:
  prices[fruit] = random.choice(price_list)

Przyjrzyjmy się parom klucz-wartość we wskazaniu domyślnych cen.

print(prices.items())
dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10)])

Podobnie jak w zwykłym słowniku Pythona, możesz uzyskać dostęp do wartości defaultdict cen za pomocą klawiszy:

prices['apple']
# 23

Spróbujmy teraz sprawdzić cenę owocu, którego nie ma, powiedzmy „pomarańczowego”. Widzimy, że zwraca domyślną wartość zero.

prices['orange']
# 0

Jeśli wydrukujemy słownik, zobaczymy, że został dodany nowy klucz „pomarańczowy” z domyślną liczbą całkowitą równą zero.

print(prices.items())
dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10), ('orange', 0)])

Defaultdict w Pythonie z listą jako wartością domyślną

Zdefiniujmy Student_Majors jako domyślny zapis list. Kluczem są nazwiska głównych kierunków. A wartości to listy studentów studiujących każdy z kierunków, takich jak matematyka, ekonomia, informatyka i inne.

from collections import defaultdict
students_majors = defaultdict(list)

Jeśli spróbujemy uzyskać dostęp do listy studentów odpowiadającej „Ekonomii”, defaultdict zwraca pustą listę; brak kluczowych błędów!

students_majors['Economics']
# []

Mamy teraz pustą listę przyporządkowaną do kierunku „Ekonomia”. Możemy więc teraz dodawać elementy do tej listy za pomocą metody listy .append().

students_majors['Economics'].append('Alex')

Utworzono wpis dla „Ekonomii” w domyślnym słowniku students_majors.

print(students_majors)
defaultdict(<class 'list'>, {'Economics': ['Alex']})

Możesz dodać więcej studentów do listy, mapując do kierunku Ekonomia, dodać nowy kierunek i wiele więcej!

students_majors['Economics'].append('Bob')
students_majors['Math'].append('Laura')
print(students_majors)
defaultdict(<class 'list'>, {'Economics': ['Alex', 'Bob'], 'Math': ['Laura']})

Wniosek

Mam nadzieję, że ten samouczek pomógł ci zrozumieć, jak i kiedy powinieneś używać defaultdict w Pythonie. Po uruchomieniu przykładów kodu w tym samouczku możesz w razie potrzeby spróbować użyć defaultdict jako preferowanej struktury danych w projektach.

Oto podsumowanie tego, czego nauczyłeś się w tym samouczku.

  • Podczas pracy ze słownikiem Pythona często natrafisz na KeyErrors.
  • Aby obsłużyć takie KeyErrors, możesz użyć kilku szczegółowych metod. Możesz użyć instrukcji warunkowych, bloków try-except lub metody .get(). Jednak typ danych defaultdict w module Collections może uprościć obsługę tego błędu klucza.
  • Możesz użyć defaultdict(default_factory), gdzie default_factory jest poprawną opcją wywołania.
  • Gdy klucz nie jest obecny w defaultdict, wartość domyślna (wywnioskowana z default_factory) i klucz są dodawane do defaultdict.

Następnie zapoznaj się z samouczkiem dotyczącym funkcji mapowania w Pythonie.