Tuplas e dicionários

Ver Todos os Exercícios

Teoria

Aí, as listas são muito importantes na computação em geral porque o agrupamento de dados é necessário em todo programa. Mas além das listas, existem outros tipos de variáveis que podem agrupar dados! Por isso, eu vim te falar sobre tuplas e dicionários agora.

Uma propriedade das listas que a gente fala bastante é a mutabilidade. A gente consegue criar uma lista e editar ela depois. Apesar de isso ser muito útil e a gente usar bastante, existem casos em que essa mutabilidade é ruim! Lembra que eu mostrei que dá pra editar a mesma lista por variáveis diferentes?? Então! Acontece que quando você tem um conjunto mutável de dados, você pode alterar alguma coisa sem querer e ferrar tudo. É exatamente aí que entram as tuplas!

Usando tuplas em Python

Cara, tuplas fazem um montão de coisas também, mas a princípio você pode pensar em tuplas como listas imutáveis. Têm as mesmas características de listas, mas não dá pra editar depois que você constrói. Olha:

Pra criar uma tupla, o processo é bem parecido com a criação de listas. Só que em vez de usar colchetes [] a gente usa parênteses mesmo (). Além disso, todo o resto é bem parecido. Olha:

Obs: Caso você não lembre, aquela notação ali dentro de [] significa que a gente quer só uma parte da tupla. A gente pegou uma fatia começando no item -1 (ultimo) até o item -3, sem contar com ele. A gente também disse que essa fatia tem que ser copiada de -1 em -1 itens (de trás pra frente). Por isso, o resultado tá invertido ali, reparou?

Mas se a gente tentar editar da mesma forma que a gente faz com listas, vai dar erro!

Viu?! Tá escrito ali que tuplas não aceitam atribuições. Não dá pra editar!

Uma das coisas mais úteis das tuplas é que a gente pode usar pra “desempacotar” uma lista ou outra tupla também. Olha esse exemplo aqui:

Repara que a gente pode usar tuplas do lado esquerdo de uma atribuição. Com isso, a gente consegue fazer várias atribuições de variável ao mesmo tempo. A gente também pode usar tuplas sem precisar criar variáveis, igual eu fiz aqui embaixo:

Também funcionaria se fosse uma lista, ok??

Mas repara que tanto nas listas quanto nas tuplas, a gente precisa saber o índice de cada item pra poder acessar ele. Mas, em alguns casos, seria bom se a gente pudesse escolher os índices manualmente, né?! Na verdade, dá pra fazer isso usando dicionários.

Usando dicionários em Python

Dicionários em Python são, assim como listas e tuplas, estruturas de agrupamento de dados. A principal característica dos dicionários é a personalização dos índices.

Pra indexar (pegar valor) de um item do dicionário a gente pode fazer da mesma forma que pra listas e tuplas, usando NOME_DA_VARIAVEL[INDICE]. Mas, diferentemente de listas, os índices podem ser qualquer tipo de valor imutável, como inteiros, floats, strings, booleans e até tuplas.

Apesar disso, os valores podem ser de QUALQUER tipo, beleza?! Só os índices que tem a limitação de precisar serem imutáveis. Mas é claro, se você tentar acessar uma key que não existe, vai dar erro.

Mas os dicionários são mutáveis e você pode acrescentar pares de key:value a qualquer momento.

Viu? Agora funcionou! Você pode acrescentar itens mesmo depois da criação do dicionário!!

Pra criar um dicionário a gente usa {} e dentro coloca os dados do nosso dicionário, com o formato {INDICE1: VALOR1, INDICE2: VALOR2 ....} e assim por diante. Também é importante saber que, em dicionários, os índices também são chamados de chaves (Keys), e provavelmente vai estar escrito Keys em vez de índice na sua prova. Ou seja, no dicionário do primeiro exemplo, a variável idades, a key “Yann” tem valor 20.

Operações com dicionário

Cara, assim como toda variável em Python, a gente pode deletar um par usando o operador del.

Além desse, a gente também pode usar o operador in, parecido com o que a gente fazia com listas!

Esse operador checa se existe alguma key com o nome que a gente perguntou. Se houver, retorna True. Caso contrário, retorna False. Nesse caso retornou True porque realmente existe uma key chamada “Nome”.

Repara que, quando a gente usou o operador in em listas, ele retornava True caso o VALOR existisse. Aqui, retorna True caso a KEY exista. Essa é a única diferença!

Por enquanto é isso, cara! Te espero pra gente fazer uns exercícios comigo!

Usando dicionários em Python

Operações com dicionário

Exercícios Resolvidos

Exercício Resolvido #1

Três tipos de dados fundamentais em Python são as listas (“lists”), sequências ou ‘tuplas’ (“tuples”) e dicionários (“dictionaries”). A respeito dessas estruturas, é correto afirmar:

  1. Listas não podem ser modificadas depois de criadas, ao passo que sequências e dicionários podem.
  2. Listas podem ser modificadas, mas seu tamanho não pode ser modificado após a criação, ao passo que sequências e dicionários não têm essa limitação.
  3. Dicionários não podem ser modificados depois de criados, ao passo que listas e sequências podem.
  4. Listas e sequências são indexadas por inteiros, ao passo que dicionários podem ser indexados por strings.
  5. Listas e dicionários são indexados por inteiros, ao passo que sequências podem ser indexadas por strings.

Passo 1

E aí, chefe! Yann aqui! Múltipla escolha dessa pra facilitar nossa vida e nosso entendimento sobre a diferença entre as principais estruturas de dados de Python…

Então bora analisar item por item até a gente encontrar o verdadeiro, jae?! Começando pelo item A, que diz que “listas não podem ser modificadas depois de criadas, ao passo que sequências e dicionários podem”.

Na verdade, listas podem sim ser modificadas! Dicionários podem também, mas não é possível fazer com tuplas. Tuplas (ou sequências) são feitas justamente pra NÃO SEREM MODIFICADAS. Então, essa tá errada, tá?! Vamo ver a próxima...

Passo 2

Bora dar uma olhada no segundo item. Tá dizendo que “listas podem ser modificadas, mas seu tamanho não pode ser modificado após a criação, ao passo que sequências e dicionários não têm essa limitação”. hmmmm

Cara, na verdade as tuplas (sequências) tem sim essa limitação… Não dá pra alterar tuplas de forma alguma, beleza?! Além disso, as listas não tem limitações de tamanho. A gente pode alterar como bem entender, tá?! Então essa também tá errada… Bora ver próxima!

Passo 3

No terceiro item, o digníssimo professor diz que “dicionários não podem ser modificados depois de criados, ao passo que listas e sequências podem”. Olha a audácia do cara! Agora há pouquinho, na teoria, a gente viu como editar dicionários… E, mais uma vez, TUPLAS NÃO PODEM SER MODIFICADAS MANOOOO!

Todos os itens estão tentando fazer a gente cair nessa, mas não vamos, ok?! Com isso, essa aqui tá errada também! Bora ver a próxima...

Passo 3

Olha, agora no item d tá escrito que “listas e sequências são indexadas por inteiros, ao passo que dicionários podem ser indexados por strings”. E é verdade! Listas e sequências são indexadas por números inteiros. Apesar de também poder ser indexado por inteiros, não há nada que impeça a gente indexar dicionários com strings. Por isso, essa alternativa tá certa!

mas, mesmo assim, bora ver a próxima pra tentar descobrir o que tem de errado nela...

Passo 4

Cara, no último item o professor teve a coragem de copiar e colar o item d. Ele diz que “listas e dicionários são indexados por inteiros, ao passo que sequências podem ser indexadas por strings”. Só não vou julgar pois eu faria o mesmo...

Mas tá dizendo que sequências podem ser indexadas por strings, e isso não é verdade. Sequências (tuplas) só podem ser indexadas, bom, em sequência hahaha! Só dá pra indexar por números inteiros, igual listas. Por isso, essa aqui realmente tá errada. E assim a gente finalizou o exercício!

heheh valeuuuu

Resposta

Alternativa d.

Exercício Resolvido #2

Escreva um programa que:

  • lê duas notas de vários alunos e armazena tais notas em um dicionário, onde a chave é o nome do aluno. A entrada de dados deve terminar quando for lida uma string vazia como nome.
  • Escreva uma função que retorna a média do aluno, dado seu nome.
  • Escreva um programa que exiba o nome é a média do aluno de maior média.

Passo 1

Fala aí, maninho! Bora começar perguntando o nome do aluno que a gente quer inserir as notas. Mas repara que tá dizendo “vários” alunos… É uma repetição indeterminada, e só nos resta usar o while pra fazer.

Mas a gente só precisa perguntar até a pessoa apertar enter sem digitar nome nenhum. Nesse caso, a gente sai do loop. Então bora programar essa parada!

Criamos uma variável chamada “notas” pra ir armazenando os nomes e as notas dos alunos. Agora a gente precisa criar a função pra calcular a média. Mas cê reparou que a gente tá guardando uma lista com as notas dentro do dicionário, né?!

Não tem problema nenhum em fazer isso. Na verdade, é a única forma de guardar mais de um valor em uma mesma key.

Passo 2

Show! Agora, bora criar a função. Cara, pra essa função eu vou te contar um segredo que seu professor provavelmente não te contou: existe uma função chamada sum() que retorna a soma de todos os elementos de uma lista. E a média é a soma de todos os elementos dividido pelo número de elementos.

Assim, essa mini função de uma linha é capaz de retornar pra gente a média do aluno que a gente passar por parâmetro. Mas a gente tem que passar também o dicionário “notas”, hein! Beleza… Agora que a nossa função tá pronta, vamos usar ela pro terceiro passo: verificar qual aluno tem a maior nota.

Passo 3

Pra isso, a gente vai ter que iterar por todos os elementos. Vamos criar, também, uma lista pra armazenar a maior nota juntamente com o nome do indivíduo. Essa lista vai ser atualizada a cada loop.

A gente passa por todos os elementos, e já calcula a média. Se a lista existir (não estiver vazia), a gente confere se o novo aluno supera o que já estava guardado lá. Mas, se a lista não existir, a gente salva nela o item e a média! Só falta a gente exibir esse resultado pro usuário...

Passo 4

E pra exibir pro usuário, a gente pode, depois do loop, chamar a função print(), dizendo o nome do doido e a média dele. Tipo assim:

Aí a gente consegue exibir, o nome e a média do cara (ou da mina) que ficou com a maior nota. E, com isso, a gente finaliza o exercício! Te vejo no próximo, doido!

Resposta

Exercício Resolvido #3

Escreva um programa para armazenar uma agenda de telefones em um dicionário. Cada pessoa pode ter um ou mais telefones e a chave do dicionário é o nome da pessoa. Seu programa deve ter as seguintes funções: ­

  • incluirNovoNome – essa função acrescenta um novo nome na agenda, com um ou mais telefones. Ela deve receber como argumentos o nome e os telefones. ­
  • incluirTelefone – essa função acrescenta um telefone em um nome existente na agenda. Caso o nome não exista na agenda, você deve perguntar se a pessoa deseja incluí-­lo. Caso a resposta seja afirmativa, use a função anterior para incluir o novo nome. ­
  • excluirTelefone – essa função exclui um telefone de uma pessoa que já está na agenda. Se a pessoa tiver apenas um telefone, ela deve ser excluída da agenda. ­
  • excluirNome – essa função exclui uma pessoa da agenda. ­
  • consultarTelefone – essa função retorna os telefones de uma pessoa na agenda.

Passo 1

Fala aí, doido! A gente precisa fazer um montão de função pra resolver essa questão aqui, mas relaxa. A próxima vai ser pior!

Mas bora fazer uma de cada vez. E repara que a doida não falou pra gente fazer nada com as funções, só criar mesmo… E nós, como bons gados de professor, vamos fazer só o que foi pedido! Bora começar pela função incluirNovoNome(); mas como nenhuma das funções recebe o dicionário como parâmetro, a gente vai ter que usar variável global…

Olha! A gente recebe o nome (String) e os números (uma lista) e cria o par key-value no dicionário. E só! Uma linha de função… Partiu criar a próxima!

Passo 2

Pô, a próxima função insere um número em uma key já criada. A gente precisa, também, verificar se essa key já foi criada (com o operador in), e se não, a gente cria com a função anterior. Se liga:

Não esquece que a gente tá guardando nos valores, listas de números. Então, quando a gente quer acrescentar um novo número, a gente usa o método de lista append(). Bora pra próxima!

Passo 3

Bora escrever a função excluirNome dessa vez. Essa função recebe o nome do indivíduo e exclui ele do dicionário. Mas, antes de deletar, a gente precisa checar se existe. Nossa função vai ficar com esse cara:

E pronto! Se aquele nome realmente existir no dicionario, a gente deleta ele. Partiu fazer a próxima função...

Passo 4

Pra fazer a função excluirTelefone, a gente pode usar a outra função que a gente criou pra deletar o contato também...

Primeiro a gente tá checando se o nome existe na agenda. Se existe, a gente confere se o telefone que recebemos pra apagar também se encontra lá na lista de números. Se tiver, a gente deleta esse telefone.

Por último, se o contato estiver sem nenhum número registrado, a gente pode deletar o nome (com a outra função que criamos, inclusive).

Passo 5

Por último, a gente precisa da função que retorna os números de uma certa pessoa. Pra isso, primeiro a gente verifica se esse contato existe, e depois retorna sua lista de números…

E pronto! Finalizamos o exercício, doido!

Resposta

Exercício Resolvido #4

Escreva uma função “inva” em Python que recebe um dicionário d e retorna um dicionário “inverso” do dicionário dado, onde, a cada valor v de d está associada a lista das chaves de d que levam a v. Exemplos:

Passo 1

E aí, mano! Precisamos fazer uma função que inverte as keys e os values de um dicionário recebido… Qual a utilidade disso?!

Também não sei, pelo menos a gente vai ficar craque em dicionários, e talvez essa tenha sido a ideia do professor. Então vamo lá! Bora começar criando o cabeçalho da função “inva”, seguindo todas as instruções do professor no enunciado:

Pronto! Repara que até o nome do parâmetro a gente copiou do enunciado, beleza! Show… Partiu pensar em como inverter os pares...

Passo 2

Mano, antes da gente começar a escrever nossa solução, tu lembra dos métodos keys() e values() que vem em todos os dicionários? Esse métodos retornam uma lista contendo seus respectivos itens, na mesma ordem… O lógica que a gente vai seguir é, a cada par key-value, a gente cria um par value-key no dicionário novo! Bom, na prática vai ficar mais claro. Vem comigo!

Pronto! Se liga que a função zip() ali facilitou muito nossa vida… Caso tu não se lembre, essa função permite a gente iterar por duas listas simultâneamente! Agora, vamos adicionar esses pares no nosso novo dicionário key-value na ordem invertida...

Passo 3

Se liga que, no novo dicionário, a gente vai usar o value como key e a key como value. A parada pode ficar meio confusa, mas a intenção da função é justamente inverter, né?! Primeiro, a gente precisa checar se aquele value já existe no novo dicionário como key.

Repara que no enunciado, todo os itens do novo dicionário são listas, mesmo os que têm apenas um elemento. Por isso, se o value (key) já existir, a gente só precisa acrescentar mais um item, e podemos usar o método de lista append() pra isso. Tipo assim:

Show! Mas se não existir, a gente precisa criar essa lista…

Beleza… Agora, a gente só precisa retornar esse novo dicionário, DEPOIS do loop terminar. Isto é, fora da endentação do for.

E pronto! Nossa função está criada…

Mas a gente precisa saber se ela tá funcionando, então bora fazer uns testes...

Passo 4

Olha, sempre que o enunciado fornecer dados de exemplo (geralmente fornece nas provas), a gente pode usar esses dados pra teste. Porque, geralmente, são esses dados que o professor vai usar pra testar na correção (lembre-se disso rsrs seja malandro).

Então bora criar os dicionários que foram usados no exemplo e testar a função com prints…

Depois de executar, o resultado foi esse aqui:

E, olha, o resultado tá exatamente igual ao do professor! Com, isso a gente garante que nossa função tá funcionando de boas. Mas não esquece que existiam MUITAS formas de fazer essa função, hein! O importante é funcionar bem que vai estar tudo ok, mesmo que o código esteja diferente dos seus colegas os professores…

E agora acabamos! Mas o enunciado tá pedindo a função inva, e não os testes. Então a gente deleta nossos testes e entrega só a função e pronto! Até a próxima, doido!

Resposta

Exercício Resolvido #5

Escreva uma função, chamada contaVoigais, que conta todas as vogais presentes no texto recebido como parâmetro e retorna um dicionário contendo a quantidade de cada vogal. Escreva um programa a fim de testar sua função, e exiba, no fim, os dados do dicionário retornado.

Passo 1

E aí, doido! Essa questão tá bem objetiva. Só nos resta obedecer.

Vamos começar criando uma função com o nome e contaVogais, que receberá por parâmetro um texto que queremos contar as vogais.

E pra gente contar as vogais, bom, a gente precisa checar letra por letra desse texto. Pra isso, a gente precisa de uma iteração. Mas antes da iteração, a gente já pode criar o dicionário que pretende retornar depois!

Com essa estrutura de repetição, a gente só precisa verificar se a letra atual é uma vogal. Se for, a gente precisa contar no dicionário. A gente pode checar se é vogal usando o operador in.

Sabendo que é uma vogal, a gente precisa contar no dicionário que criamos com o nome de “contador”. Pra isso, a gente verifica se já tem essa key no dicionário. Se já tiver, a gente acrescenta 1, mas se não tiver, a gente adiciona.

E pronto! Repara que a diferença é pequena entre acrescentar e adicionar um item ao dicionário! Por fim, a gente precisa retornar o dicionário criado no fim da função.

Passo 2

Agora que a gente já tem a função que conta as vogais, a gente pode escrever o programa pra receber o texto do usuário e mandar a função contar pra gente! Bora pedir o texto com a função input.

Depois de contar as vogais, a gente precisa iterar pelo dicionário pra exibir pro usuário quantas vogais de cada existia no texto. Pra isso, a gente vai fazer mais um laço de repetição, um for.

Não esquece que a iteração passa somente pelas keys, ok? Aí, pra acessar o valor armazenado, a gente tem que usar a notação DICIONARIO[KEY}. E é isso! Terminamos o exercício! Até o próximo, ok?!

Resposta

Exercício Resolvido #6

A conta do cartão de crédito de uma pessoa pode ser modelada por um dicionário com os campos saldo, com o saldo devedor da conta, transações, com o número de transações que gerou esse saldo, e média, com a média de gastos por transação. Escreva uma função compra, que recebe como parâmetros o dicionário com a conta e o valor da compra e retorna um novo dicionário para aquela conta, com o saldo devedor, número de transações e média de gastos atualizados.

Passo 1

Fala aí, peixe! A gente precisa escrever uma função que recebe um dicionário e retorna outro com algumas modificações… Então bora lá! Começa escrevendo o cabeçalho da função:

Com os parâmetros que também foram especificados pelo enunciado, ok?! A primeira coisa que a gente tem que fazer agora é uma cópia do dicionário recebido. Isso porque os dicionários são mutáveis, e se a gente editar esse dicionário, os efeitos vão surgir no item que foi passado por parâmetro também! E, apesar de ser útil nesse caso, não é isso que o enunciado quer… Tá escrito “um novo dicionário” ali! Então, bora pegar um cópia:

Show! Agora, a variável “conta” passou a armazenar uma cópia do dicionário que tinha antes. Agora, a gente pode editar sem medo… Começando pelo número de transações, que deve aumentar em 1, já que a gente fez uma compra (o nome da função, né).

Além disso, deve ser acrescentado na fatura o preço da nova compra do usuário, então bora somar o dado na chave “saldo”, assim como especificou o enunciado:

E, pra atualizar o último item, precisamos calcular a média. E a média é dada pelo saldo dividido pelo número de transações…

E não podemos esquecer de retornar nosso novo dicionário atualizado, ok?!

Passo 2

Cara, o enunciado não tá mandando a gente fazer nenhum teste, mas é sempre bom fazer… Se estiver funcionando certinho, aí a gente pode apagar o que a gente escreveu. Bora criar um dicionário com os elementos zerados:

E agora, vamos importar o módulo random e fazer um loop adicionando compras aleatórias na nossa conta.

Depois de executar, o resultado pareceu estar funcionando de boas, cara!

E, com isso, a gente conclui que nossa função tá funcionando. Vamos apagar nossos testes e entregar só a função, assim como o enunciado pediu, ok?! Valeuuu

Resposta

Exercício Resolvido #7

Faça um programa que leia nomes de alunos e suas respectivas notas até que o nome ’oooo’ seja informado, após o fim da leitura, imprima o nome do aluno que possui a maior nota. Obs.: Use dicionário para resolver essa questão.

Passo 1

Fala aí, guerreiro sayajin! A ideia é perguntar nome e nota de alunos e adicionar em um dicionário. Como a gente precisa repetir esse processo até que o nome inserido seja “oooo”, então a gente tem um caso de repetição indeterminada, que vamos precisar resolver com um laço while. Então bora começar!

Como não sabemos quando o loop precisa parar, a gente pode construir um loop infinito e, quando for digitado ‘oooo’, a gente usa a palavra-chave break pra sair do loop. Então bora perguntar o nome com a função input();

Pronto! Se o usuário digitar aquela parada ali, igual tá no enunciado, o loop vai parar. Mas, caso não digite, a gente precisa perguntar a nota e depois salvar num dicionário. Acontece que a gente nem criou esse dicionário ainda… Bora criar!

Show! Vamos pensar agora sobre como pegar o aluno de maior nota...

Passo 2

Cara, pra gente checar qual dos alunos tem a maior nota, a gente pode fazer uma iteração e comparar todos os alunos, salvando o maior dentro de uma variável...

O método notas.items() retorna uma lista de tuplas que a gente pode iterar ao mesmo tempo por nome e nota (nessa ordem). Se não tiver ninguém adicionado como maior nota ainda, então a gente adiciona. Se já tiver alguém lá, a gente verifica se a nota dele realmente é maior que a atual e atualizamos se necessário. Por último, a gente só precisa exibir pro usuário o nome do indivíduo que ficou em maior_nota.

E pronto! Finalizamos o exercício, ok?! Até o próximo!

Resposta

Exercício Resolvido #8

Faça uma função que encontre todas as chaves que estão associadas a um determinado valor em um dicionário. A função receberá no primeiro parâmetro o dicionário a ser analisado, e como segundo parâmetro o valor da chave a ser buscada. A função retornará uma lista com as chaves encontradas, essa lista pode ter diversos valores, apenas um ou nenhum. Nos exemplos, a função foi chamada de p r o c u r a R e v e r s a .

Exemplo:

Passo 1

O enunciado nos diz o suficiente para conseguirmos definir o escopo da função p r o c u r a R e v e r s a , por esse motivo iremos começar por ela:

Pronto, agora temos a função p r o c u r a R e v e r s a , que espera como parâmetros um dicionário e um valor de chave, definida.

Passo 2

O enunciado nos diz que caso haja uma chave de valor correspondente no dicionário, a mesma deve ser armazenada em um lista. Por esse motivo, devemos declarar essa lista logo no início da função:

Passo 3

Agora temos que pensar em uma lógica para adicionarmos as chaves que possuem valores correspondentes ao passado pelo parâmetro em uma lista. Para isso, podemos utilizar a estrutura de repetição for:

Onde verificaremos a cada loop do laço de repetição for se o valor da chave iterada naquele momento do dicionário é igual a v a l o r , caso seja, basta adicionarmos através do método de lista append a chave v na lista c h a v e s . Caso contrário, as iterações irão continuar até que todas as chaves do dicionário tenham sido verificadas.

Passo 4

Por fim, para finalizarmos a nossa função, basta retornarmos a lista c h a v e s de todas as chaves em que os seus valores deram “match” com o valor passado como parâmetro:

Resposta

Ei, a resposta está no passo a passo :)