Dicionários#
Um dicionário em Python é uma estrutura de dados que armazena pares de chave-valor. É a primeira estrutura não ordenada que vamos aprender.
Cada chave deve ser única e imutável (por exemplo, uma string, um número ou uma tupla), enquanto os valores podem ser de qualquer tipo, incluindo listas, listas e até mesmo outros dicionários.
Os dicionários são úteis para armazenar dados que precisam ser rapidamente acessíveis por uma chave descritiva.
Aqui você encontra a documentação oficial de dicionários, cobrindo todos as operações que vamos falar neste capítulo.
Sintaxe básica#
Um dicionário é definido usando chaves {}
e cada par de chave-valor é separado por dois pontos :
. Os pares são separados por vírgulas ,
.
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
print(pessoa)
{'nome': 'João', 'idade': 30, 'cidade': 'São Paulo'}
Operações básicas com dicionários#
Acessando valores a partir da chave#
Lembra que com listas e tuplas podemos acessar os elementos pela índice? Pois bem, em dicionário é como se nós atribuíssemos nomes aos índices. Os índices passam a ser as nossas chaves. E ao acessarmos a chave de um dicionário o valor é retornado.
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
print(pessoa["nome"])
João
Note que não existe mais o acesso por índices ou posições, como era em listas e tuplas. Por este motivo, os dicionários são estruturas não ordenadas. Não há uma ordem (primeiro, segundo, terceiro) para acessarmos os valores. Vejamos o que acontece caso busquemos pelo primeiro par de chaves e valores através de índices:
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
print(pessoa[0])
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Cell In[3], line 2
1 pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
----> 2 print(pessoa[0])
KeyError: 0
Esse erro KeyError: 0
ocorre porque o código tentou acessar a chave 0 no dicionário, mas essa chave não existe. As únicas chaves presentes no dicionário são nome
, idade
e cidade
. Em resumo, o erro significa que a chave 0 não foi encontrada.
Modificando o dicionário#
Dicionários são mutáveis assim como listas. Ou seja, uma vez criado, eu consigo modificar seus valores, bem como acrescentar ou remover outros pares de chave e valor.
Se buscarmos por uma chave, por exemplo, profissao
, no dicionário pessoa
criado acima através da notação pessoa["profissao"]
vamos receber a mensagem de erro KeyError: 'profissão'
, conforme já vimos. Porém, podemos atribuir um valor a esta chave inexistente, e ela será criada.
# pessoa não possui a chave profissão
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
# Aqui não estamos acessando a chave profissão, mas sim criando-a!
pessoa["profissao"] = "desenvolvedor"
print(pessoa)
{'nome': 'João', 'idade': 30, 'cidade': 'São Paulo', 'profissao': 'desenvolvedor'}
Nota (acessar vs atribuir)
Lembre-se que acessar é diferente de atribuir. Para acessar, a chave precisa existir. Na atribuição, se a chave não existir, ela será criada.
Caso uma atribuição seja feita a uma chave existente, o valor dela será substituído.
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
# O valor correspondente à chave "nome" é substituid por "José"
pessoa["nome"] = "José"
print(pessoa)
{'nome': 'José', 'idade': 30, 'cidade': 'São Paulo'}
É possível remover pares de chave-valor de um dicionário de duas formas: usando o método pop
de dicionários ou usando a instrução del
. Vejamos:
Usando a instrução del
, o par é simplesmente apagado não sendo possível salvá-lo em variáveis.
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
# O par de chave-valor correspondente à chave nome deixou de existir
del pessoa["nome"]
print(pessoa)
{'idade': 30, 'cidade': 'São Paulo'}
Já com o método pop
, o par de chave-valor é removido, e o valor é salvo na variável definida.
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
# O par de chave-valor correspondente à chave nome deixou de existir
idade = pessoa.pop("idade")
print(idade)
print(pessoa)
30
{'nome': 'João', 'cidade': 'São Paulo'}
Métodos comuns de dicionários#
get
#
O método get
é uma outra forma de acessar uma determinada chave de um dicionário. Ele retorna o valor associado à chave especificada. Porém, diferente do acesso dict['chave']
como vimos acima, se a chave não existir, retorna None ou um valor padrão definido. Vamos ver este método com o mesmo exemplo acima:
# pessoa não possui a chave profissão
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
# Acessando uma chave inexistente com o método get()
print(pessoa.get("profissao"))
# Caso a chave não exista, podemos passar um valor padrão que será retornado
print(pessoa.get("profissao", "desenvolvedor"))
None
desenvolvedor
O grande diferencial ao usar o método get
é que nunca teremos o erro KeyError
no caso de acessar uma chave inexistente. Eu, particularmente, considero até uma forma mais segura de acessar chaves de um dicionário através deste método.
keys
, values
e items
#
Estes 3 métodos são basicamente para listar as chaves (keys
), valores (values
) e pares de chave-valor (items
) de um dicionário.
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
# Aqui serão impressas somente as chaves do dicionário
print(pessoa.keys())
# Aqui serão impressas somente os valores do dicionário
print(pessoa.values())
# E finalmente a combinação dos pares de chave-valor
print(pessoa.items())
dict_keys(['nome', 'idade', 'cidade'])
dict_values(['João', 30, 'São Paulo'])
dict_items([('nome', 'João'), ('idade', 30), ('cidade', 'São Paulo')])
O último método items
em especial é bem interessante. Ele retorna algo similar à uma lista de tuplas, e cada tupla contém 2 elementos, a chave e o seu respectivo valor. Vamos retornar à este método quando formos aprender sobre laços de repetição for
.
Outras operações com dicionários#
Podemos medir a quantidade de pares chave-valor através da função len
.
pessoa = {"nome": "João", "idade": 30, "cidade": "São Paulo"}
print(len(pessoa))
3
É possível trabalhar com junções e atualizações de vários dicionários usando os operadores |
e |=
.
Nota (operadores de junção/atualização)
Ambos os operadores |
e |=
só estão disponíveis nas versões do Python 3.9+. Caso estes operadores sejam usados em códigos Python executados na versão 3.8 ou anterior, o código apresentará um erro!
O operador |
une os pares de chave e valor de dois dicionários, criando um terceiro dicionário.
informacoes_basicas_produto = {"nome": "Cadeira", "preco": 150, "codigo": "abc"}
informacoes_adicionais_produto = {"cor": "azul", "estoque": 20, "codigo": "xyz"}
informacoes_produto = informacoes_basicas_produto | informacoes_adicionais_produto
print(informacoes_produto)
{'nome': 'Cadeira', 'preco': 150, 'codigo': 'xyz', 'cor': 'azul', 'estoque': 20}
Se dois dicionários têm a mesma chave e você os une com a | b
, o valor da chave no dicionário final será o do dicionário b
, que está à direita na união. Ou seja, os valores do dicionário b
prevalecem sobre os do dicionário a
quando há chaves iguais. Foi o que aconteceu com a chave codigo
no exemplo acima.
Já o operador |=
é usado para atualizar um dicionário existente, combinando-o com outro dicionário.
cliente = {"nome": "Maria", "idade": 28, "possui_conveio": True}
novas_informacoes = {
"email": "maria@example.com",
"idade": 29,
"possui_convenio": False,
}
cliente |= novas_informacoes
print(cliente)
{'nome': 'Maria', 'idade': 29, 'possui_conveio': True, 'email': 'maria@example.com', 'possui_convenio': False}
A diferença entre |
e |=
está na maneira como eles combinam dicionários.
O operador |
cria um novo dicionário resultante da combinação de dois dicionários, sem modificar os originais. No exemplo acima, os dicionários informacoes_basicas_produto
e informacoes_adicionais_produto
mantiveram-se inalterados.
Já o operador |=
atualiza diretamente o dicionário à esquerda com os pares chave-valor do dicionário à direita, modificando-o. O dicionário cliente
no exemplo foi alterado.
Portanto, podemos afirmar que |
é uma operação imutável, e |=
é mutável.
Prática#
Vamos colocar a mão na massa? O exercício 10 é um mega exercício super completo que usa um contexto real de negócios!
Conclusão#
Neste capítulo, exploramos os dicionários, uma estrutura de dados não ordenada fundamental em Python que permite mapear chaves a valores de forma eficiente. Aprendemos como criar, acessar, modificar e remover elementos, além de métodos úteis como get
, keys
, values
e items
. Na sequência, vamos aprender sobre a última estrutura de dados básicas de Python: os conjuntos.