Como e quando você deve usar Defaultdict em Python?

Neste tutorial, você aprenderá a usar defaultdict do módulo de coleções do Python — para lidar melhor com KeyErrors — ao trabalhar com dicionários do Python.

Em Python, um dicionário é uma poderosa estrutura de dados integrada que armazena dados em pares chave-valor. Você usará as teclas para acessar o dicionário e acessar os valores.

No entanto, quando você tem vários dicionários em seu script Python que são modificados durante a execução do código, muitas vezes você encontrará KeyErrors. E existem algumas maneiras diferentes de lidar com eles.

Neste tutorial, você aprenderá:

  • O que são KeyErrors e por que eles surgem
  • Como lidar com KeyErrors
  • Como usar o defaultdict do Python, uma subclasse que herda da classe dict integrada, para lidar melhor com as chaves ausentes

Vamos começar!

O que são KeyErrors em Python?

Ao definir um dicionário Python, você deve tomar cuidado para garantir o seguinte:

  • As chaves devem ser únicas – sem qualquer repetição.
  • Ao usar um iterável existente como as chaves de um dicionário, você deve preferir usar uma coleção imutável, como uma tupla.

Portanto, uma chave só é válida se estiver presente no dicionário; caso contrário, leva a KeyErrors.

Considere o seguinte dicionário, books_authors, no qual as chaves são os nomes dos livros e os valores são os nomes dos autores.

Você pode codificar junto com este tutorial em um Python REPL.

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

Você pode usar a chave (nome do livro) para acessar o nome do autor.

books_authors['Hyperfocus']
'Chris Bailey'

Para acessar todos os pares chave-valor no dicionário, você pode chamar o método items() no objeto do dicionário, conforme mostrado abaixo:

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

Se você tentar acessar o valor de uma chave que não está presente no dicionário, o interpretador Python gera um KeyError. Encontramos KeyError quando tentamos acessar o valor de chaves que não existem, ou seja, ‘Grit’ e ‘chave inexistente’.

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'

Então, como você lida com KeyErrors em Python?

  Como fazer texto diagonal no Word

Existem algumas maneiras de fazer isso, e vamos aprendê-las na próxima seção.

Como lidar com KeyErrors em Python

Vamos aprender como lidar com KeyErrors usando:

  • Instruções condicionais if-else
  • Blocos Try-except
  • O método de dicionário .get()

#1. Usando instruções condicionais If-Else

Uma das maneiras mais simples de lidar com KeyErrors em Python é usar as instruções condicionais if-else.

Em Python, as instruções if-else têm a seguinte sintaxe geral:

 if condition:
 	# do this 
 else:
    # do something else 
  • Se a condição for True, as instruções no corpo if são executadas e
  • Se a condição for False, as instruções no corpo do else serão executadas.

Neste exemplo, a condição é verificar se a chave está presente no dicionário.

Se a chave estiver presente no dicionário, o operador in retornará True, e se body será executado imprimindo o valor correspondente.

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

# Output
# Neil Pasricha

Se a chave não estiver presente no dicionário, o operador in retornará False e o corpo else será executado. Ele imprime uma mensagem de que a chave não está presente.

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. Usando instruções Try-Except

Outro método comum para lidar com KeyError é usar as instruções try-except em Python.

Leia o seguinte bloco de código:

key = 'non-existent-key'
try:
  print(books_authors[key])
except KeyError:
  print('Sorry, this key does not exist!')
  • O bloco try tenta recuperar o valor correspondente à chave fornecida.
  • Se a chave não estiver presente, o interpretador gera um KeyError que é tratado como uma exceção dentro do bloco except.

#3. Usando o método .get()

Em Python, você pode usar o método de dicionário integrado .get() para lidar com chaves ausentes.

A sintaxe geral para usar o método get() é dict.get(key,default_value) onde dict é um objeto de dicionário válido em Python.

  Como pesquisar um tópico online

– Se a chave estiver presente no dicionário, o método get() retornará o valor.
– Caso contrário, ele retorna o valor padrão.

Neste exemplo, keys é uma lista de chaves cujos valores gostaríamos de acessar. Percorremos a lista de chaves para recuperar os valores correspondentes do dicionário books_authors.

Aqui, usamos o método .get() com ‘Não existe’ como valor padrão.

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

No código acima:

  • Para chaves presentes no dicionário books_authors, o método .get() retorna os valores correspondentes.
  • Quando as chaves não existem, neste caso, ‘Grit’ e ‘Make Time’, o método .get() retorna o valor padrão ‘Não existe’.
# Output

Does not exist
Chris Bailey
Does not exist
Cal Newport

Todos os métodos acima nos ajudam a lidar com erros importantes. No entanto, eles são detalhados e exigem que manipulemos explicitamente as chaves ausentes. Você pode simplificar esse processo usando um defaultdict em vez de um dicionário normal.

Defaultdict em Python

O defaultdict é uma subclasse da classe dictionary (dict). Portanto, ele herda o comportamento de um dicionário Python. Além disso, ele também lida com chaves ausentes nativamente.

O defaultdict é um tipo de dados de contêiner que está embutido na biblioteca padrão do Python – dentro do módulo de coleções.

Então você deve importá-lo para o seu ambiente de trabalho:

from collections import defaultdict

Aqui está a sintaxe geral para usar defaultdict:

defaultdict(default_factory)

Você pode especificar um callable como int, float ou list como o atributo default_factory. Se você não fornecer um valor para default_factory, o padrão será Nenhum.

Quando a chave que você está procurando não está presente, o método __missing__() é acionado e infere o valor padrão do default_factory. Em seguida, ele retorna esse valor padrão.

Resumindo:

  • Em Python, um defaultdict retorna o valor padrão quando a chave não está presente.
  • Ele também adiciona esse par chave-valor padrão ao dicionário, que você pode modificar.

Exemplos de Python Defaultdict

Em seguida, codificaremos alguns exemplos para entender como o Python defaultdict funciona.

Defaultdict em Python com valor inteiro padrão

Primeiro, importe defaultdict do módulo de coleções.

from collections import defaultdict
import random

Vamos criar um defaultdict de preços.

prices = defaultdict(int)

Agora, preenchemos o dicionário de preços usando os itens da lista de frutas como chaves. E amostramos valores aleatoriamente da lista_preços para obter os valores.

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

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

Vamos dar uma olhada nos pares de valores-chave no defaultdict de preços.

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

Como um dicionário Python normal, você pode acessar os valores do defaultdict de preços usando as chaves:

prices['apple']
# 23

Agora, vamos tentar acessar o preço de uma fruta que não está presente, digamos, ‘laranja’. Vemos que ele retorna o valor padrão de zero.

prices['orange']
# 0

Se imprimirmos o dicionário, veremos que uma nova chave ‘laranja’ foi adicionada com o valor inteiro padrão de zero.

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

Defaultdict em Python com List como o valor padrão

Vamos definir students_majors como um padrão de listas. Os nomes dos majores são as chaves. E os valores são as listas de alunos que cursam cada um dos cursos, como matemática, economia, ciência da computação e muito mais.

from collections import defaultdict
students_majors = defaultdict(list)

Se tentarmos acessar a lista de alunos correspondente a ‘Economia’, defaultdict retorna uma lista vazia; sem erros de chave!

students_majors['Economics']
# []

Agora temos uma lista vazia mapeada para o curso de ‘Economia’. Portanto, agora podemos adicionar elementos a esta lista usando o método de lista .append().

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

Uma entrada foi criada para ‘Economia’ no dicionário padrão students_majors.

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

Você pode adicionar mais alunos ao mapeamento da lista para o curso de Economia, adicionar um novo curso e muito mais!

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

Conclusão

Espero que este tutorial tenha ajudado você a entender como e quando você deve usar defaultdict em Python. Depois de executar os exemplos de código neste tutorial, você pode tentar usar defaultdict como a estrutura de dados preferencial em seus projetos quando necessário.

  Como baixar todas as fotos de uma conversa do Messenger

Aqui está um resumo do que você aprendeu neste tutorial.

  • Ao trabalhar com um dicionário Python, muitas vezes você encontrará KeyErrors.
  • Para lidar com esses KeyErrors, você pode usar alguns métodos detalhados. Você pode usar instruções condicionais, blocos try-except ou o método .get(). Mas o tipo de dados defaultdict no módulo de coleções pode simplificar esse tratamento de KeyError.
  • Você pode usar defaultdict(default_factory) onde default_factory é um callable válido.
  • Quando a chave não está presente no defaultdict, o valor padrão (inferido de default_factory) e a chave são adicionados ao defaultdict.

Em seguida, confira o tutorial sobre a função de mapa do Python.