Dicionários

Objetivo

Ao final dessa aula você vai saber o que são dicionários e como utilizá-los na resolução de problemas computacionais.

Tópicos

Dicionários

Vimos que as listas em Python são estruturas sequenciais indexadas, onde cada elemento da lista pode ser acessado por um índice (um número inteiro).

Em algumas situações, ao invés de utilizar um número inteiro como índice, desejamos utilizar alguma informação, como por exemplo, o nome de um objeto.

Vamos definir um dicionário como sendo um tipo abstrato de dados que associa uma chave a um valor. A chave precisa ser única, ou seja, não pode haver chaves repetidas e também deve ser imutável, ou seja, uma vez criada, ela permanece a mesma.

Um dicionário pode ser utilizado, por exemplo, para representar um inventório. Considere por exemplo, o seguinte programa:

def main():
    dic = Dicionario()

    dic.insere("banana", 50)
    dic.insere("abacaxi", 20)
    dic.insere("melancia", 5)
    print(dic)

    print("Eu tenho", dic.pega_valor("banana"), " bananas.")

    dic.insere("banana", dic.pega_valor("banana")+10)
    print("Agora tenho ", dic.pega_valor("banana"), " bananas.")

Esse programa ilustra que um dicionário precisa de um método insere e outro método pega_valor (entre outros).

Exercício 22.1

Baseado na função main dada anteriormente, implemente uma classe Dicionario que tenha o comportamento (os métodos) definidos pela main, usando 2 listas. Teste a sua classe usando a própria função main.

(aula22_classe_Dicionario_tentativa)



Clique aqui para ver uma solução.

Melhorando a classe Dicionario

Assim como podemos mudar o comportamento dos símbolos usados em operadores usando métodos especiais como __add__ (+), __sub__`(-) e `__mul__`(`*) (veja a aula 18), a seguinte notação pode ser mais apropriada para o nosso dicionário:

def main():
    dic = Dicionario()

    dic["banana"] = 50
    dic["abacaxi"] = 20
    dic["melancia"] = 5
    print(dic)

    print("Bananas: ", dic["banana"])

    dic["banana"] = dic["banana"]+10
    print("Bananas: ", dic["banana"])

Nessa notação, os nomes das frutas usadas como chave no dicionário aparecem como se fossem índices de uma lista. O Python permite redefinir o comportamento dos colchetes usando os métodos especiais __getitem__ e __setitem__.

O método especial __getitem__ é chamado automaticamente quando um objeto dessa classe é chamado com colchetes para obter o valor associado a um “índice”. Assim, dic[‘melancia’] é equivalente à chamada:

Dicionario.__getitem__(dic, 'melancia')

e, em nosso caso, deve devolver uma referência ao valor correspondente em dic.valor[i], onde i e o índice da chave melancia na lista dic.chave.

O método especial __setitem__ é chamado automaticamente em atribuições como:

dic['banana'] = 50

Esse comando é equivalente a:

Dicionario.__setitem__(dic, 'banana', 50)

Exercício 22.2

Modifique a classe Dicionario para utilizar os métodos especiais __setitem__ e __getitem__.

Observação

Os métodos especiais __setitem__ e __getitem__ ainda não foram implementados no activecode. Por isso, você vai precisar fazer os testes desse método em seu computador.

Tipo dict (dicionário) nativo do Python

O Python possui o tipo nativo dict que permite a criação e manipulação de dicionários. Para se criar um dicionário vazio, utilize:

>>> dic = {}

ou seja, use chaves ao invés de colchetes usados na criação de listas.

Você também pode criar dicionários com elementos, separando a chave do valor usando : (dois pontos) como:

>>> dic = {'banana':50, 'abacaxi':10}
>>> print(dic)
{'banana': 50, 'abacaxi': 10}

E você pode usar as chaves entre colchetes para criar ou modificar um elemento do dicionário como:

>>> dic = {'banana':50, 'abacaxi':10}
>>> print(dic)
{'banana': 50, 'abacaxi': 10}
>>> dic["melancia"] = 7
>>> print(dic)
{'banana': 50, 'abacaxi': 10, 'melancia': 7}
>>> dic['banana'] += 15
>>> print(dic)
{'banana': 65, 'abacaxi': 10, 'melancia': 7}
>>>

Acesso aos elementos do dicionário

É tão comum iterar sobre as chaves de um dicionário que podemos utilizar o comando for para imprimir (ou fazer outras operações com) os valores associados a cada item do inventório da seguinte forma:

(exemplo_iteracao_sobre_chaves_de_um_dicionario)



Essa é uma forma compacta para se iterar sobre as chaves de um dicionário, que pode ser feita de forma explícita utilizando o método keys() da forma:

(exemplo_iteracao_sobre_chaves_de_um_dicionario_usando_keys)



É possível também iterar sobre os valores de um dicionário utilizando o método values(). Assim, para saber quantas frutas há no inventário podemos escrever:

(exemplo_iteracao_sobre_valores_de_um_dicionario)



Exercício 22.3

Matrizes esparsas tipicamente possuem zero em quase todas as posições, e valores diferentes de zero em apenas algumas posições.

Uma matriz esparsa pode ser representada como um dicionário, utilizando as coordenadas como chave.

Seja a seguinte matriz esparsa representando um campo de batalha naval, com um submarino valendo 100 pontos, um cruzador valendo 30 pontos (cada pedaço), e um porta-aviões valendo 20 pontos (cada pedaço). O “mar”, onde estão as embarcações, tem coordenadas de 0 a 99, tanto em x quanto em y.

Escreva um programa que carrega um mapa usando a função dada carrega_mapa e leia coordenadas do usuário até que ele desista, imprimindo os pontos que ganhou, ou até que afunde todas as embarcações (ganhe o máximo número de pontos possível no mapa).

Uma estratégia possível é contar inicialmente quantos pontos são possíveis fazer no jogo e modificar o valor associado a uma posição definida no dicionário para zero, toda vez que o usuário acertar uma embarcação. O jogo acaba quando não restarem mais pontos para serem ganhos. Para isso, implemente uma função total_pontos que retorna o número de pontos ainda disponível no dicionário.

(ex22_3_batalha_naval_tentativa)



Observação

Na função carrega_mapa() estamos utilizando o string “(2,5)” ao invés de uma tupla (2,5) por limitações do activecode. O Python aceita como chave qualquer objeto imutável como (2,5) (experimente escrever sua solução no Python em seu computador).

Clique aqui para ver uma solução para rodar em seu computdor.

Exercício 22.4

Escreva um programa que leia uma frase e calcula a frequência relativa de cada letra em uma frase, usando dicionários. Ignore caracteres brancos e pontuação.

(aula22_4_freq_letras_tentativa)



Clique aqui para ver uma solução.

Exercício 22.5

Escreva um programa que leia um arquivo texto e calcula a frequência relativa de cada palavra no texto, usando dicionários.