Hur och när ska du använda Defaultdict i Python?

By rik

Denna genomgång ger dig kunskap om hur du effektivt använder `defaultdict` från Pythons samlingsmodul, vilket ger en elegant lösning för att hantera `KeyError` när du arbetar med Python-ordböcker.

En ordbok i Python är en central datastruktur som hanterar information i form av nyckel-värdepar. Du använder nycklarna för att enkelt navigera och få tillgång till de associerade värdena.

När ditt Python-skript involverar flera ordböcker som ändras under körning, är det vanligt att stöta på `KeyError`. Det finns lyckligtvis ett antal sätt att hantera dessa fel.

I denna artikel kommer du att utforska:

  • Grunderna bakom `KeyError` och dess vanliga orsaker.
  • Olika metoder för att hantera `KeyError` effektivt.
  • Hur du kan dra nytta av Pythons `defaultdict`, en underklass som ärver från `dict`-klassen, för att förbättra hanteringen av saknade nycklar.

Låt oss börja!

Vad är `KeyError` i Python?

När du skapar en ordbok i Python är det viktigt att notera följande:

  • Nycklar måste vara unika; dubbletter är inte tillåtna.
  • Om du använder ett befintligt iterabelt objekt som nycklar, är det rekommenderat att använda en oföränderlig samling, som en tupel.

En nyckel är giltig endast om den finns i ordboken; annars resulterar det i ett `KeyError`.

Tänk dig en ordbok, `books_authors`, där bokens namn är nycklarna och författarnas namn är värdena.

Du kan följa med genom att kopiera koden i en Python REPL.

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

Du kan komma åt författarens namn genom att använda bokens namn som nyckel.

        books_authors['Hyperfocus']
        'Chris Bailey'
    

För att hämta alla nyckel-värdepar kan du använda metoden `items()` på ordboksobjektet, som visas här:

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

Om du försöker nå ett värde med en nyckel som inte finns i ordboken, kommer Python-tolken att kasta ett `KeyError`. Det här felet inträffar när vi försöker få tillgång till värden för obefintliga nycklar, som `Grit` och `non-existent key`.

        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'
    

Så, hur hanterar du `KeyError` i Python?

Det finns flera metoder, som vi kommer att utforska i nästa avsnitt.

Metoder för att Hantera `KeyError` i Python

Låt oss undersöka hur du hanterar `KeyError` med hjälp av:

  • `if`-`else` villkorssatser
  • `try`-`except` block
  • Ordboksmetoden `.get()`

#1. Använda `if`-`else` villkorssatser

Ett grundläggande sätt att hantera `KeyError` är att använda `if`-`else` villkorssatser.

I Python har `if`-`else`-satser följande grundläggande struktur:

        if villkor:
            # utför detta
        else:
            # utför något annat
    
  • Om villkoret är sant, körs satsen inom `if`-blocket.
  • Om villkoret är falskt, körs satsen inom `else`-blocket.

I detta fall kontrollerar villkoret om nyckeln finns i ordboken.

Om nyckeln finns, returnerar `in`-operatorn `True`, och det motsvarande värdet skrivs ut.

        key = 'The Happiness Equation'
        if key in books_authors:
            print(books_authors[key])
        else:
            print('Tyvärr, den här nyckeln finns inte!')

        # Output
        # Neil Pasricha
    

Om nyckeln inte finns, returnerar `in`-operatorn `False` och `else`-blocket körs, och meddelandet om att nyckeln inte finns visas.

        key = 'non-existent-key'
        if key in books_authors:
            print(books_authors[key])
        else:
            print('Tyvärr, den här nyckeln finns inte!')

        # Output
        # Tyvärr, den här nyckeln finns inte!
    

#2. Använda `try`-`except` block

Ett annat vanligt sätt att hantera `KeyError` är att använda `try`-`except`-satser i Python.

Ta en titt på följande kod:

        key = 'non-existent-key'
        try:
            print(books_authors[key])
        except KeyError:
            print('Tyvärr, den här nyckeln finns inte!')
    
  • `try`-blocket försöker hämta värdet som motsvarar nyckeln.
  • Om nyckeln inte finns, skapas ett `KeyError` som hanteras av `except`-blocket.

#3. Använda Metoden `.get()`

I Python kan du använda den inbyggda ordboksmetoden `.get()` för att hantera saknade nycklar.

Den allmänna syntaxen är `dict.get(nyckel, default_värde)`, där `dict` är ett ordboksobjekt i Python.

– Om nyckeln finns i ordboken returnerar `.get()` värdet.
– Annars returnerar den `default_värde`.

I det här exemplet är `keys` en lista med nycklar vars värden vi vill nå. Vi loopar genom listan för att hämta motsvarande värden från ordboken `books_authors`.

Vi har använt metoden `.get()` med `’Finns inte’` som standardvärde.

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

I koden ovan:

  • För nycklar som finns i `books_authors` returnerar `.get()` motsvarande värden.
  • När nycklar inte finns, som i fallet med `Grit` och `Make Time`, returnerar `.get()` standardvärdet `Finns inte`.
        # Output

        Finns inte
        Chris Bailey
        Finns inte
        Cal Newport
    

Alla ovanstående metoder hjälper oss att hantera `KeyError`. Men de är detaljerade och kräver att vi explicit hanterar de saknade nycklarna. Du kan förenkla denna process genom att använda en `defaultdict` istället för en standardordbok.

`Defaultdict` i Python

En `defaultdict` är en underklass till `dict`-klassen. Den ärver alltså en Python-ordboks egenskaper. Dessutom hanterar den saknade nycklar inbyggt.

`Defaultdict` är en containerdatatyp som finns i Pythons standardbibliotek – i modulen `collections`.

Du måste alltså importera den till din arbetsmiljö:

        from collections import defaultdict
    

Här är den grundläggande syntaxen för att använda `defaultdict`:

        defaultdict(default_factory)
    

Du kan ange en callable som `int`, `float` eller `list` som `default_factory`-attributet. Om du inte anger ett värde för `default_factory`, är det som standard `None`.

När nyckeln du söker inte finns, aktiveras metoden `__missing__()` och den hämtar standardvärdet från `default_factory`. Det här standardvärdet returneras sedan.

Sammanfattningsvis:

  • En `defaultdict` i Python returnerar standardvärdet när nyckeln saknas.
  • Den lägger även till detta nyckel-standardvärdepar till ordboken, vilket du sedan kan ändra.

Exempel på `Defaultdict` i Python

Låt oss se på några kodexempel för att bättre förstå hur `defaultdict` fungerar i Python.

`Defaultdict` med standardheltalsvärde

Importera först `defaultdict` från `collections`-modulen.

        from collections import defaultdict
        import random
    

Låt oss skapa en `defaultdict` för priser.

        prices = defaultdict(int)
    

Vi fyller nu `prices`-ordboken med frukterna som nycklar och slumpmässiga priser som värden.

        price_list = [10,23,12,19,5]
        fruits = ['äpple','jordgubbe','granatäpple','blåbär']

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

Låt oss se nyckel-värdeparen i `prices`.

        print(prices.items())
    
        dict_items([('äpple', 12), ('blåbär', 19), ('granatäpple', 5), ('jordgubbe', 10)])
    

Precis som en vanlig Python-ordbok, kan du komma åt värden i `prices` med hjälp av nycklarna:

        prices['äpple']
        # 23
    

Låt oss nu försöka komma åt priset för en frukt som inte finns, säg ’apelsin’. Vi ser att den returnerar standardvärdet noll.

        prices['apelsin']
        # 0
    

Om vi skriver ut ordboken ser vi att en ny nyckel, ’apelsin’, har lagts till med standardheltalsvärdet noll.

        print(prices.items())
    
        dict_items([('äpple', 12), ('blåbär', 19), ('granatäpple', 5), ('jordgubbe', 10), ('apelsin', 0)])
    

`Defaultdict` med lista som standardvärde

Låt oss definiera `students_majors` som en `defaultdict` av listor. Namnen på ämnena är nycklarna, och värdena är listorna över studenter som studerar respektive ämne (matematik, ekonomi, datavetenskap, etc.).

        from collections import defaultdict
        students_majors = defaultdict(list)
    

Om vi försöker komma åt listan av studenter som studerar ’Ekonomi’, returnerar `defaultdict` en tom lista; inga `KeyError`!

        students_majors['Ekonomi']
        # []
    

Vi har nu en tom lista kopplad till ’Ekonomi’. Vi kan lägga till element i denna lista med listmetoden `.append()`.

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

En post har skapats för ’Ekonomi’ i ordboken `students_majors`.

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

Du kan lägga till fler studenter i Ekonomilistan, lägga till nya ämnen och mycket mer!

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

Sammanfattning

Jag hoppas att den här guiden har gett dig en djupare förståelse för hur och när du ska använda `defaultdict` i Python. Efter att ha utforskat de medföljande kodexemplen, kan du överväga att använda `defaultdict` som din primära datastruktur i dina projekt, där det är relevant.

Här är en sammanfattning av det du lärt dig:

  • När du arbetar med Python-ordböcker kan `KeyError` uppstå.
  • För att hantera dessa fel kan du använda flera metoder. Du kan använda villkorssatser, `try`-`except`-block eller metoden `.get()`. `Defaultdict`-datatypen i `collections`-modulen kan förenkla hanteringen.
  • Du använder `defaultdict(default_factory)`, där `default_factory` är en giltig callable.
  • Om en nyckel saknas i `defaultdict`, läggs standardvärdet (hämtat från `default_factory`) till, tillsammans med nyckeln.

Ta en titt på artikeln om Python-kartfunktionen.