[Py-Intro] Aula 04

Tipos básicos e estruturas de controles

O que você vai aprender nesta aula?

Após o término da aula você terá aprendido:

  • Formatação de strings
  • Conjuntos: set
  • Mapeamentos: dicionários

Formatação de strings

Complementando a aula passada será explicado melhor como funciona a função format() e str.format() começando pela última.

A função str.format() converte os campos envolvos por chaves pelos argumentos passados a ela. Caso não seja especificado o nome ou posição dos argumentos a troca de chaves por dados é feita na ordem:


In [1]:
'{} + {} = {}'.format(10, 10, 20)


Out[1]:
'10 + 10 = 20'

Porém podemos especificar explicitamente as posições que queremos substituir:


In [2]:
'{0} + {1} = {2}'.format(10, 10, 20)  # esse é o padrão


Out[2]:
'10 + 10 = 20'

Podemos repetir um único argumento:


In [3]:
'{0} + {0} = {1}'.format(10, 20)


Out[3]:
'10 + 10 = 20'

Informar uma ordem arbritária:


In [4]:
'{1} + {0} = {2}'.format(30, 20, 10)  # evite fazer isso para não causar confusão


Out[4]:
'20 + 30 = 10'

Também é possível dar nomes a esses campos:


In [5]:
string = '{cidade} é muito bonito(a) durante o(a) {estação}'
string.format(cidade='Bruxelas', estação='Inverno')


Out[5]:
'Bruxelas é muito bonito(a) durante o(a) Inverno'

Também podemos formatar números:


In [6]:
'O total é R${0}'.format(59.8912313)


Out[6]:
'O total é R$59.8912313'

In [7]:
'O total é R${0:.2f}'.format(59.8912313)


Out[7]:
'O total é R$59.89'

In [8]:
'A porcentagem é de {0:.2%}'.format(0.8912313)


Out[8]:
'A porcentagem é de 89.12%'

format() também permite alinhar elementos dentro de um espaço de 10 caracteres:


In [9]:
'{0:<10} | {1:<10} | {2:<10}'.format('Qtd.', 'Cor', 'Valor')  # alinhado à esquerda


Out[9]:
'Qtd.       | Cor        | Valor     '

In [10]:
'{0:>10} | {1:>10} | {2:>10}'.format('Qtd.', 'Cor', 'Valor')  # alinhado à direita


Out[10]:
'      Qtd. |        Cor |      Valor'

O tamanho do espaço pode ser diferente nos elementos:


In [11]:
'{0:^6} | {1:^9} | {2:^10}'.format('Qtd.', 'Cor', 'Valor')  # centralizado


Out[11]:
' Qtd.  |    Cor    |   Valor   '

Também é possível mudar o caracter de preenchimento do espaço dado de caracter em branco para algum outro:


In [12]:
'{0:+^6} | {1:=^9} | {2:-^10}'.format('Qtd.', 'Cor', 'Valor')  # centralizado


Out[12]:
'+Qtd.+ | ===Cor=== | --Valor---'

In [13]:
'{0:+^6} | {1:=^9} | {2:-^10}'.format('Qtd.', 'Cor', 'Valor')  # centralizado


Out[13]:
'+Qtd.+ | ===Cor=== | --Valor---'

Também podemos armazenar format e reaplicá-los para valores diferentes:


In [14]:
formato_tabela = '{0:^6} | {1:^9} | {2:^10}'
formato_tabela


Out[14]:
'{0:^6} | {1:^9} | {2:^10}'

In [15]:
produtos = [
    (2, 'Amarelo', 18.50),
    (5, 'Verde', 48.50),
    (2, 'Azul', 78.50),
]
produtos


Out[15]:
[(2, 'Amarelo', 18.5), (5, 'Verde', 48.5), (2, 'Azul', 78.5)]

In [16]:
print(formato_tabela.format('Qtd.', 'Cor', 'Valor R$'))
for qtd, cor, valor in produtos:
    print(formato_tabela.format(qtd, cor, valor))


 Qtd.  |    Cor    |  Valor R$ 
  2    |  Amarelo  |    18.5   
  5    |   Verde   |    48.5   
  2    |   Azul    |    78.5   

Também é possível especificar o tipo dos dados:


In [17]:
'{0:e} {0:f} {0:%}'.format(.0000031)


Out[17]:
'3.100000e-06 0.000003 0.000310%'

Os formatos possíveis são:

Também é possível formatar valores usando a função embutida format():


In [18]:
import math

format(math.pi, '6.3f')


Out[18]:
' 3.142'

In [19]:
format('Python', '.<12')


Out[19]:
'Python......'

In [20]:
format('Python', '.>12')


Out[20]:
'......Python'

In [21]:
format('Python', '.^12')


Out[21]:
'...Python...'

Diferentemente da função str.format() a função embutida format() não permite substituição de caracteres usando chaves.

Para saber mais sobre o assunto consulte a documentação e este documento feito pelo Luciano Ramalho que explica detalhadamente como usar essa função.

Tipos básicos - conjuntos e mapeamentos

Na aula passada vimos outros tipos básicos: números e sequência.

Agora vamos falar sobre conjuntos.

Set (conjunto)

Conjunto, ou set, é uma ferramenta subutilizada do Python, tanto que muitos cursos introdutórios não passam abordam esse assunto.

Set vem da teoria de conjuntos da matemática. Um conjunto não permite a existência de elementos iguais dentro de si, por conta disso é muito utilizado para remover repetições:


In [22]:
l = ['spam', 'spam', 'eggs', 'spam']
l


Out[22]:
['spam', 'spam', 'eggs', 'spam']

In [23]:
set(l)


Out[23]:
{'eggs', 'spam'}

Como podemos ver a sintaxe de set - {1}, {1, 2}, etc. - se parece exatamente com a notação matemática, com exceção que não existe uma notação para set vazio. Caso você precise criar um conjunto vazio use: set().


In [24]:
A = set()
len(a)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-24-bf2aaa473a28> in <module>()
      1 A = set()
----> 2 len(a)

NameError: name 'a' is not defined

Vale lembrar que conjuntos também se comportam como sequências, por conta disso é possível usar neles as funções que aprendemos anteriormente:


In [25]:
A = {5, 4, 3, 3, 2, 10}
A


Out[25]:
{2, 3, 4, 5, 10}

In [26]:
len(A)


Out[26]:
5

In [27]:
sum(A)


Out[27]:
24

In [28]:
max(A)


Out[28]:
10

In [29]:
min(A)


Out[29]:
2

Um ponto importante a se observar é que conjunto não mantém a ordem dos elementos:


In [30]:
A = {4, 5, 1, 3, 4, 5, 7}
A  # ordem diferente da declarada!


Out[30]:
{1, 3, 4, 5, 7}

Por isso não é possível acessar os elementos pela posição:


In [31]:
A[0]


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-31-3f7632ffc2df> in <module>()
----> 1 A[0]

TypeError: 'set' object does not support indexing

É possível acessar seus elementos iterando o set:


In [32]:
for num in A:
    print(num)


1
3
4
5
7

Ou convertendo-o para tupla ou lista:


In [33]:
tuple(A)


Out[33]:
(1, 3, 4, 5, 7)

In [34]:
tuple(A)[0]


Out[34]:
1

In [35]:
list(A)


Out[35]:
[1, 3, 4, 5, 7]

In [36]:
list(A)[-1]


Out[36]:
7

Assim como listas os conjuntos também possuem um mecanismo simplificado para construir conjuntos o set comprehension:


In [37]:
{letra for letra in 'abrakadabraalakazam'}


Out[37]:
{'a', 'b', 'd', 'k', 'l', 'm', 'r', 'z'}

In [38]:
{numero for numero in range(30) if numero % 3 != 0}


Out[38]:
{1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29}

Outra característica importante de conjuntos é que eles realizam verificações de pertencimento de forma muito mais eficiente.

Para verificar se um elemento está presente em um conjunto usamos o mesmo operador in que vimos para lista, tuplas e string:


In [4]:
A = {-10, 0, 10, 20, 30, 40}
A


Out[4]:
{-10, 0, 10, 20, 30, 40}

In [5]:
5 in A


Out[5]:
False

In [6]:
-10 in A


Out[6]:
True

Para demonstrar que conjuntos verificam se um elemento pertence em uma coleção de maneira mais rápida isso vamos usar o módulo timeit que oferece uma maneira simples de contar o tempo de execução de código Python.

O módulo timeit possui uma função timeit(stmt='pass', setup='pass', number=1000000, ...) que executa um setup e um código (stmt) uma dada quantidade de vezes e contabiliza o tempo levado para executar o código (o tempo de rodar o setup não é incluído). O código e o setup devem ser passados como strings.


In [39]:
import timeit

tempo = timeit.timeit('[math.exp(x) for x in range(10)]', setup='import math')
tempo


Out[39]:
2.4771713519985497

O código acima executa primeiro o setup import math depois o código [math.exp(x) for x in range(10)], que cria uma lista com os exponencianciais de 0 a 9, 1000000 vezes.

Para sabermos qual a média do tempo de execução desse código fazemos:


In [40]:
tempo / 1000000


Out[40]:
2.4771713519985495e-06

Sabendo disso agora podemos calcular o tempo de verificação de um elemento em lista e set:


In [41]:
import timeit
import random

# PS: esse código demora para ser executado
vezes = 1000
print('tamanho  | tempo da lista | tempo do set | list vs set')
tamanhos = (10 ** i for i in range(3, 8))
for tamanho in tamanhos:  # cria um gerador com os valores 10^3, 10^4, ..., 10^7
    setup_lista = 'l = list(range({}))'.format(tamanho)
    tempo = timeit.timeit('9999999 in l', setup=setup_lista, number=vezes)
    media_lista = tempo / vezes
    
    setup_set = 's = set(range({}))'.format(tamanho)
    tempo = timeit.timeit('9999999 in s', setup=setup_set, number=vezes)
    media_set = tempo / vezes
    
    msg = '{:<9}| {:<15}| {:<13}| set é {:<}x + rápido'
    msg = msg.format(tamanho, round(media_lista, 8), round(media_set, 8),
                     round(media_lista / media_set))
    print(msg)


tamanho  | tempo da lista | tempo do set | list vs set
1000     | 2.573e-05      | 3e-08        | set é 888x + rápido
10000    | 0.00017057     | 4e-08        | set é 3997x + rápido
100000   | 0.00165465     | 4e-08        | set é 37923x + rápido
1000000  | 0.01546964     | 3e-08        | set é 494918x + rápido
10000000 | 0.14962824     | 6e-08        | set é 2717154x + rápido

Esse código usa alguns recursos mais avançados de formatação de string. Para entender melhor o que é feito verifique a documentação oficial do assunto.

Conjuntos também oferecem algumas operações interessantes:

União $${(A \cup B)}$$

A união pode ser feita a partir da função A.union(B) ou através da utilização do operador bitwise ou | :


In [42]:
A = {2, 3, 4}
B = {3, 5, 7}
A | B


Out[42]:
{2, 3, 4, 5, 7}

In [43]:
A.union(B)


Out[43]:
{2, 3, 4, 5, 7}

Intersecção $${A \cap B}$$

A intersecção pode ser feita a partir da função A.intersection(B) ou com o operador bitwise e & :


In [44]:
A = {2, 3, 4}
B = {3, 5, 7}
A & B


Out[44]:
{3}

In [45]:
A.intersection(B)


Out[45]:
{3}

Diferença $${A - B}$$

A diferença pode ser feita a partir da função A.difference(B) ou com o operador - :


In [46]:
A = {2, 3, 4}
B = {3, 5, 7}
A - B


Out[46]:
{2, 4}

In [47]:
A = {2, 3, 4}
B = {3, 5, 7}
A.difference(B)


Out[47]:
{2, 4}

Diferença simétrica $${A \bigtriangleup B}$$

A diferença pode ser feita a partir da função A.difference(B) ou com o operador ^ :


In [48]:
A = {2, 3, 4}
B = {3, 5, 7}
A ^ B


Out[48]:
{2, 4, 5, 7}

In [49]:
A.symmetric_difference(B)


Out[49]:
{2, 4, 5, 7}

Ok, essas funções são legais, mas eu já vi isso no ensino médio e nunca usei na minha vida, como isso vai ser útil para mim? (pelo menos foi isso que eu pensei ao ver isso)

Para testar isso vamos gerar um conjunto de nomes. Vamos usar a biblioteca externa faker que gera dados falsos.

Para usá-la é necessário instalar:

$ pip install fake-factory

Depois de instalá-la em nosso virtualenv podemos usá-la:


In [50]:
from faker import Factory

factory = Factory.create('pt_BR')  # criando fábrica de dados falsos português brasileiro
nomes = {factory.name() for _ in range(10000)}
nomes


Out[50]:
{'Nina Correia',
 'Eduardo Rocha',
 'Joaquim Martins',
 'Sra. Bruna Ferreira',
 'Lívia Barbosa',
 'Srta. Ana Ferreira',
 'Pedro Henrique Ribeiro',
 'Letícia Martins',
 'Dra. Ana Sophia Araújo',
 'Thomas Melo',
 'Nicolas Dias',
 'Srta. Maria Cecília Pereira',
 'João Guilherme Cardoso',
 'Bryan Azevedo',
 'Lavínia Martins',
 'Valentina Barbosa',
 'Sr. Isaac Castro',
 'Sr. Renan Cunha',
 'Pedro Lucas Lima',
 'Olivia Pereira',
 'Laura Rocha',
 'Bernardo Santos',
 'Ana Lívia Azevedo',
 'Mariane Rodrigues',
 'Clarice Almeida',
 'Sofia Gomes',
 'Theo Ribeiro',
 'Dra. Maria Fernanda Castro',
 'Heloísa Carvalho',
 'Diogo Castro',
 'Fernando Ferreira',
 'Sra. Camila Costela',
 'Letícia Carvalho',
 'Juliana Silva',
 'Miguel Pereira',
 'Ryan Dias',
 'Isabel Pereira',
 'Emanuel Correia',
 'Dr. Diogo Ferreira',
 'Dr. Marcos Vinicius Alves',
 'Murilo Correia',
 'Sr. Marcelo Pereira',
 'Benjamin Fernandes',
 'Luiz Felipe Fernandes',
 'Esther Costela',
 'Isabelly Souza',
 'Sra. Heloísa Costela',
 'Arthur Melo',
 'Sr. João Lucas Santos',
 'Luiz Miguel Araújo',
 'Nina Alves',
 'Stephany Alves',
 'Lucas Ribeiro',
 'Enzo Gabriel Castro',
 'Catarina Ferreira',
 'Sr. Raul Barros',
 'Daniel Melo',
 'Lucas Gabriel Barros',
 'Melissa Costela',
 'Dr. Thiago Lima',
 'Maria Julia Barbosa',
 'Sr. Nicolas Carvalho',
 'Olivia Alves',
 'Maria Sophia Ribeiro',
 'Emanuella Pereira',
 'Luiz Fernando Rocha',
 'Heloísa Silva',
 'Lavínia Araújo',
 'Dr. Luiz Felipe Costela',
 'Ana Beatriz Fernandes',
 'Dra. Bruna Dias',
 'Pedro Miguel Ferreira',
 'Dr. Vitor Costela',
 'Emilly Alves',
 'Paulo Santos',
 'Dra. Daniela Cardoso',
 'Luiz Otávio Gomes',
 'Murilo Souza',
 'Mirella Barros',
 'Dr. Anthony Alves',
 'Dr. Guilherme Dias',
 'Esther Barros',
 'Leandro Correia',
 'André Rodrigues',
 'Igor Souza',
 'Camila Alves',
 'Dr. Emanuel Santos',
 'Lara Carvalho',
 'Maria Alice Araújo',
 'Maria Cecília Cardoso',
 'Kevin Ribeiro',
 'Sabrina Cunha',
 'Srta. Alícia Cunha',
 'Calebe Pereira',
 'João Guilherme Oliveira',
 'Vitória Silva',
 'Srta. Emanuelly Rodrigues',
 'Sra. Olivia Cardoso',
 'Emanuella Azevedo',
 'Marina Barbosa',
 'Maria Sophia Gomes',
 'Dra. Alice Araújo',
 'Luana Barbosa',
 'Dr. Bryan Rodrigues',
 'Srta. Gabriela Lima',
 'Mariana Carvalho',
 'Melissa Barros',
 'Sr. Nathan Rodrigues',
 'Thomas Barros',
 'Bryan Almeida',
 'Sra. Letícia Pereira',
 'Benjamin Costela',
 'Sra. Ana Carolina Pinto',
 'Vinicius Melo',
 'Davi Lucca Silva',
 'Thiago Santos',
 'Isaac Almeida',
 'Marcela Lima',
 'Marcela Ribeiro',
 'Enrico Almeida',
 'Daniel Costela',
 'Isabella Barros',
 'Sr. Nicolas Ribeiro',
 'Bruno Alves',
 'Sr. Benjamin Ferreira',
 'Sr. Marcelo Fernandes',
 'Davi Martins',
 'André Azevedo',
 'Rafael Pinto',
 'Henrique Oliveira',
 'Catarina Cardoso',
 'Nathan Alves',
 'Nicole Dias',
 'Pedro Miguel Castro',
 'Erick Cunha',
 'Davi Lucca Santos',
 'Manuela Barbosa',
 'Maria Sophia Souza',
 'Mariane Ferreira',
 'Fernanda Pereira',
 'Bruno Castro',
 'Calebe Dias',
 'Pedro Henrique Santos',
 'Laura Martins',
 'Marina Alves',
 'Letícia Cardoso',
 'Maria Clara Pereira',
 'Bryan Ribeiro',
 'Srta. Milena Pinto',
 'Milena Souza',
 'Vicente Carvalho',
 'Stella Gomes',
 'Raquel Cunha',
 'Isabelly Oliveira',
 'Henrique Almeida',
 'Stella Carvalho',
 'Sr. Theo Rodrigues',
 'Gustavo Azevedo',
 'Ana Sophia Pereira',
 'Sra. Maria Alice Pereira',
 'Sra. Mariana Martins',
 'Sr. Otávio Almeida',
 'Dr. Benício Araújo',
 'Laura Castro',
 'Ana Dias',
 'Davi Lucca Castro',
 'Rafaela Carvalho',
 'Lorena Castro',
 'Valentina Souza',
 'Srta. Emilly Fernandes',
 'Bryan Oliveira',
 'Dra. Eduarda Araújo',
 'Bernardo Ribeiro',
 'Maria Sophia Cardoso',
 'Sr. Arthur Ribeiro',
 'Daniel Rocha',
 'Stephany Almeida',
 'Mariana Dias',
 'Luana Correia',
 'Sr. João Gomes',
 'Stella Dias',
 'Luiz Henrique Rodrigues',
 'Pedro Correia',
 'Davi Lucca Rocha',
 'Alícia Barbosa',
 'Thomas Oliveira',
 'Agatha Cunha',
 'Sr. João Guilherme Gomes',
 'Vitor Gabriel Araújo',
 'Dr. Joaquim Ferreira',
 'Stella Pereira',
 'Felipe Santos',
 'Antonio Pinto',
 'Maria Vitória Rodrigues',
 'Sr. Luiz Otávio Fernandes',
 'André Correia',
 'Isabella Barbosa',
 'Cecília Costela',
 'Maria Cecília Rodrigues',
 'Sr. Caio Melo',
 'Carlos Eduardo Souza',
 'Theo Cunha',
 'Lavínia Alves',
 'Sra. Isadora Almeida',
 'Arthur Barros',
 'Lívia Santos',
 'Daniela Cunha',
 'Breno Almeida',
 'Carolina Barros',
 'Isadora Melo',
 'Srta. Rebeca Rocha',
 'Gabrielly Santos',
 'Ana Clara Ferreira',
 'Sabrina Barbosa',
 'Emilly Ferreira',
 'Maria Eduarda Rodrigues',
 'Maria Julia Silva',
 'Dr. Pedro Miguel Santos',
 'Dr. Thales Fernandes',
 'Dra. Laís Costela',
 'Agatha Cardoso',
 'Sra. Beatriz Ribeiro',
 'Giovanna Santos',
 'Sra. Ana Carolina Correia',
 'Maria Luiza Araújo',
 'Thiago Alves',
 'Luiza Martins',
 'Nicole Fernandes',
 'Luana Alves',
 'Sra. Fernanda Santos',
 'Sophie Souza',
 'Lucas Gabriel Correia',
 'Isadora Ribeiro',
 'Leonardo Cunha',
 'Julia Castro',
 'Valentina Martins',
 'Luigi Costela',
 'Matheus Martins',
 'Carolina Gomes',
 'Sr. Lorenzo Cunha',
 'Dr. Theo Cardoso',
 'Dr. Theo Ferreira',
 'Esther Ferreira',
 'Dr. Calebe Barbosa',
 'Srta. Giovanna Ribeiro',
 'Sra. Isabelly Araújo',
 'Sra. Vitória Melo',
 'Isabel Costela',
 'Dr. Renan Correia',
 'Cecília Lima',
 'Dra. Emanuelly Correia',
 'Maria Julia Fernandes',
 'Mirella Silva',
 'Dr. João Costela',
 'Isabelly Azevedo',
 'Luana Ferreira',
 'Valentina Santos',
 'Srta. Manuela Castro',
 'Melissa Souza',
 'Caroline Cardoso',
 'Maria Martins',
 'Sr. Theo Lima',
 'Dra. Ana Laura Barbosa',
 'Dr. Marcos Vinicius Silva',
 'Valentina Araújo',
 'Eloah Barros',
 'Dra. Ana Lívia Alves',
 'Ryan Santos',
 'Eduarda Lima',
 'Sofia Pereira',
 'Sra. Bianca Carvalho',
 'Giovanna Gomes',
 'Dra. Ana Sophia Azevedo',
 'Sr. Luiz Gustavo Souza',
 'Thiago Araújo',
 'Ian Santos',
 'Sra. Yasmin Cunha',
 'Otávio Gomes',
 'Vitor Dias',
 'Maria Luiza Azevedo',
 'Dra. Heloísa Azevedo',
 'Erick Castro',
 'Dr. Leandro Santos',
 'Yago Pinto',
 'Alexia Correia',
 'Diogo Barros',
 'Brenda Correia',
 'Sr. João Lucas Fernandes',
 'Julia Melo',
 'Bárbara Ribeiro',
 'Sra. Maria Alice Dias',
 'Sr. Davi Lucca Barros',
 'André Silva',
 'Dr. João Guilherme Martins',
 'Sr. Pedro Miguel Araújo',
 'Dra. Julia Rodrigues',
 'Emanuella Barbosa',
 'Dra. Laura Oliveira',
 'Nicole Cardoso',
 'Benício Ribeiro',
 'Eduardo Ribeiro',
 'Ana Vitória Carvalho',
 'Sr. Gustavo Henrique Martins',
 'João Pedro Barros',
 'Gabriela Ribeiro',
 'Ana Julia Correia',
 'Dr. Davi Lucca Pereira',
 'Arthur Rocha',
 'Sra. Alexia Correia',
 'Maysa Pinto',
 'Dr. Juan Almeida',
 'Emanuelly Rocha',
 'Dr. Cauê Cunha',
 'Marcela Carvalho',
 'Ana Lívia Araújo',
 'Srta. Maitê Costela',
 'João Pedro Souza',
 'Dra. Manuela Carvalho',
 'Sr. Eduardo Almeida',
 'Rafaela Almeida',
 'Heitor Pinto',
 'Samuel Carvalho',
 'Amanda Souza',
 'Nicole Martins',
 'Davi Cardoso',
 'Sr. Matheus Fernandes',
 'Davi Gomes',
 'Dr. Bernardo Carvalho',
 'Leonardo Oliveira',
 'Murilo Oliveira',
 'Maitê Melo',
 'Luiz Gustavo Ferreira',
 'Sarah Cardoso',
 'Sra. Sophie Rodrigues',
 'Isabel Fernandes',
 'Guilherme Alves',
 'Dra. Emilly Costela',
 'Carolina Pereira',
 'Carolina Lima',
 'Dr. Francisco Gomes',
 'Noah Fernandes',
 'Noah Souza',
 'Sra. Ana Carolina Ribeiro',
 'Agatha Correia',
 'Dr. Luigi Cunha',
 'Sophie Martins',
 'Ana Vitória Ferreira',
 'Sarah Araújo',
 'Sra. Natália Barbosa',
 'Maria Eduarda Castro',
 'Srta. Maysa Castro',
 'Dra. Stephany Barros',
 'Yago Souza',
 'Emanuella Castro',
 'Dr. João Vitor Almeida',
 'Kevin Santos',
 'Emanuella Costela',
 'Caroline Souza',
 'Beatriz Melo',
 'Alana Castro',
 'Dr. Diogo Pereira',
 'Kaique Rocha',
 'Thales Pinto',
 'Fernando Azevedo',
 'Pedro Henrique Alves',
 'Alana Carvalho',
 'Breno Ferreira',
 'Luiz Felipe Dias',
 'Valentina Castro',
 'Luiz Felipe Cardoso',
 'Daniela Correia',
 'Lorenzo Carvalho',
 'Ana Clara Azevedo',
 'Marcelo Rodrigues',
 'Luiz Miguel Melo',
 'Carlos Eduardo Correia',
 'Miguel Alves',
 'Ana Oliveira',
 'Sra. Natália Santos',
 'Augusto Ribeiro',
 'Stella Silva',
 'Cauê Cunha',
 'Sra. Amanda Lima',
 'Sra. Carolina Costela',
 'Dr. Noah Souza',
 'Bernardo Alves',
 'Nathan Rocha',
 'Lorenzo Melo',
 'Carlos Eduardo Barros',
 'Lucca Carvalho',
 'Yuri Cardoso',
 'Bernardo Costela',
 'Elisa Lima',
 'Dra. Luana Azevedo',
 'Joaquim Dias',
 'Sra. Maria Alice Fernandes',
 'Otávio Castro',
 'Esther Araújo',
 'Anthony Costela',
 'Maria Luiza Silva',
 'Dr. Heitor Melo',
 'Dr. Cauê Alves',
 'Nina Oliveira',
 'Srta. Marcela Ferreira',
 'Sophie Oliveira',
 'Vitória Carvalho',
 'Srta. Caroline Carvalho',
 'João Miguel Carvalho',
 'Dr. Ryan Barbosa',
 'Ian Barbosa',
 'Amanda Barbosa',
 'Kaique Araújo',
 'Raul Gomes',
 'Theo Ferreira',
 'Luiz Gustavo Almeida',
 'Catarina Dias',
 'Manuela Almeida',
 'Bárbara Fernandes',
 'Sr. Murilo Cunha',
 'Ana Sophia Almeida',
 'Dr. João Vitor Silva',
 'Laura Pinto',
 'Maria Julia Araújo',
 'Maria Sophia Cunha',
 'Maria Cecília Fernandes',
 'Bruno Lima',
 'Srta. Lívia Barbosa',
 'Lucca Rodrigues',
 'Sra. Alícia Rodrigues',
 'Sr. João Vitor Cardoso',
 'Davi Barbosa',
 'Arthur Silva',
 'Luna Araújo',
 'Agatha Martins',
 'Sra. Mirella Ribeiro',
 'João Santos',
 'Dr. Anthony Dias',
 'Sr. João Felipe Barros',
 'Olivia Barros',
 'Arthur Ferreira',
 'Sra. Larissa Castro',
 'Sra. Brenda Barbosa',
 'Maria Eduarda Martins',
 'Sr. Luiz Otávio Carvalho',
 'Noah Barbosa',
 'Pedro Henrique Martins',
 'Srta. Maysa Melo',
 'Henrique Silva',
 'Rebeca Barbosa',
 'Renan Rodrigues',
 'Pedro Araújo',
 'Isabelly Santos',
 'Dr. Pedro Miguel Rocha',
 'Gustavo Castro',
 'Marcos Vinicius Martins',
 'Catarina Carvalho',
 'Sr. Kevin Costela',
 'Enrico Oliveira',
 'Luna Ribeiro',
 'Bruna Ribeiro',
 'Dr. Henrique Castro',
 'André Lima',
 'Benício Cunha',
 'Luna Cardoso',
 'Emanuel Rocha',
 'Gustavo Ferreira',
 'Ana Araújo',
 'Stella Fernandes',
 'Enzo Gabriel Alves',
 'Paulo Fernandes',
 'Lucca Melo',
 'Camila Gomes',
 'Ana Julia Cunha',
 'Maysa Dias',
 'Yago Cunha',
 'Ryan Fernandes',
 'Esther Oliveira',
 'Isadora Pinto',
 'Sra. Mariana Pinto',
 'Ana Clara Dias',
 'Dr. Alexandre Costela',
 'Emanuel Almeida',
 'Vitor Correia',
 'Dr. Pedro Henrique Ribeiro',
 'Alice Cardoso',
 'Igor Pereira',
 'Giovanna Carvalho',
 'Joana Ferreira',
 'Dra. Brenda Azevedo',
 'Laura Araújo',
 'Mirella Costela',
 'Sarah Costela',
 'Benício Silva',
 'Clara Gomes',
 'Rafael Cardoso',
 'Olivia Gomes',
 'Isadora Almeida',
 'Maysa Rodrigues',
 'Natália Pereira',
 'Sr. Pedro Costela',
 'Davi Lucas Pereira',
 'Danilo Santos',
 'Vitor Carvalho',
 'Sr. Miguel Santos',
 'Gustavo Henrique Alves',
 'Dra. Valentina Rocha',
 'Bruna Pinto',
 'Raul Souza',
 'Gabriel Pinto',
 'Bernardo Melo',
 'Marcos Vinicius Rodrigues',
 'Nicolas Almeida',
 'Ana Lívia Pinto',
 'Ana Clara Santos',
 'Amanda Rodrigues',
 'Alana Rodrigues',
 'Sra. Maria Sophia Oliveira',
 'Erick Dias',
 'Ana Carolina Gomes',
 'Srta. Pietra Barros',
 'Nicole Araújo',
 'Dra. Gabrielly Correia',
 'Kamilly Azevedo',
 'Luiz Henrique Barbosa',
 'Vitor Hugo Lima',
 'Isadora Cardoso',
 'Marcela Rodrigues',
 'Nicolas Lima',
 'Ana Clara Rodrigues',
 'Lavínia Souza',
 'Dr. Benício Cardoso',
 'Yuri Dias',
 'Dr. João Pedro Barbosa',
 'Vicente Alves',
 'Nicole Santos',
 'Luiz Henrique Alves',
 'Ana Sophia Correia',
 'João Guilherme Silva',
 'Sr. Joaquim Barbosa',
 'Dr. Arthur Gomes',
 'Nathan Azevedo',
 'Antonio Silva',
 'Sra. Melissa Araújo',
 'Cauã Cunha',
 'Luiza Silva',
 'Laura Barbosa',
 'Gabriel Azevedo',
 'Dra. Mirella Correia',
 'Amanda Pinto',
 'Murilo Barbosa',
 'Laís Santos',
 'Stephany Pereira',
 'Isabel Correia',
 'Cauã Martins',
 'Enzo Gabriel Cunha',
 'Srta. Daniela Martins',
 'Dr. Vicente Rodrigues',
 'Maria Julia Rodrigues',
 'Luiz Otávio Cardoso',
 'Vitor Hugo Castro',
 'Dra. Heloísa Pereira',
 'Camila Pereira',
 'Ian Cardoso',
 'Julia Santos',
 'Eloah Fernandes',
 'Nicole Melo',
 'Enrico Santos',
 'Rafael Dias',
 'Catarina Gomes',
 'Emilly Rodrigues',
 'Sophie Silva',
 'Dr. Ryan Ribeiro',
 'Esther Lima',
 'Maysa Souza',
 'Rebeca Silva',
 'Sr. Luiz Henrique Azevedo',
 'Gabrielly Almeida',
 'Levi Rocha',
 'Elisa Cardoso',
 'Isaac Pinto',
 'Srta. Stella Santos',
 'Ana Lívia Pereira',
 'Sra. Cecília Araújo',
 'Ana Vitória Alves',
 'Srta. Rebeca Rodrigues',
 'Evelyn Costela',
 'Vitor Gabriel Carvalho',
 'Lívia Costela',
 'Raul Dias',
 'Maria Julia Alves',
 'Sabrina Martins',
 'Marcelo Alves',
 'Eduardo Oliveira',
 'Sra. Ana Araújo',
 'João Lucas Pinto',
 'Brenda Rodrigues',
 'Sra. Sophie Melo',
 'Elisa Rodrigues',
 'Joana Rocha',
 'Pietro Barbosa',
 'Lucas Martins',
 'Nina Gomes',
 'Luiza Carvalho',
 'Sr. Paulo Pinto',
 'Maria Vitória Dias',
 'Dra. Clara Castro',
 'Sra. Maria Clara Carvalho',
 'Sra. Camila Alves',
 'Dr. Lucca Alves',
 'Srta. Ana Beatriz Almeida',
 'Sra. Sophie Costela',
 'Amanda Carvalho',
 'Dr. Henrique Rocha',
 'Bianca Rocha',
 'Marcelo Barros',
 'Sophie Correia',
 'Helena Gomes',
 'Manuela Santos',
 'Vitor Gabriel Fernandes',
 'Valentina Alves',
 'Luna Lima',
 'Eduardo Barros',
 'Ana Martins',
 'Benjamin Ribeiro',
 'André Rocha',
 'João Barbosa',
 'Pedro Miguel Pereira',
 'Alana Gomes',
 'Srta. Caroline Cardoso',
 'Clarice Melo',
 'Erick Lima',
 'Dr. Vicente Azevedo',
 'Srta. Emilly Barbosa',
 'Antonio Fernandes',
 'Bernardo Pinto',
 'Thiago Castro',
 'Bruno Ribeiro',
 'Dr. Pedro Lucas Cardoso',
 'Dra. Sabrina Costela',
 'Felipe Pinto',
 'João Miguel Lima',
 'João Gabriel Fernandes',
 'Dr. Alexandre Melo',
 'Dr. Noah Pereira',
 'Sra. Juliana Oliveira',
 'Gabriela Cardoso',
 'Srta. Lorena Fernandes',
 'Maria Costela',
 'Mirella Souza',
 'Maria Eduarda Rocha',
 'Mariane Lima',
 'Alexandre Cunha',
 'Ian Araújo',
 'Paulo Oliveira',
 'Ana Lívia Lima',
 'Cauã Castro',
 'Luiz Otávio Martins',
 'Nina Castro',
 'Gabriel Correia',
 'Maria Clara Rocha',
 'Luiz Otávio Lima',
 'Isabella Costela',
 'Henrique Araújo',
 'Sr. Cauê Silva',
 'Srta. Clara Dias',
 'Ana Beatriz Castro',
 'Theo Correia',
 'Sr. Thales Araújo',
 'Isabelly Pereira',
 'Maria Eduarda Cardoso',
 'Sr. Samuel Castro',
 'Sr. Benício Martins',
 'Srta. Vitória Alves',
 'Srta. Lorena Barros',
 'Rodrigo Gomes',
 'Luana Silva',
 'Srta. Ana Carolina Azevedo',
 'Dr. Kevin Santos',
 'Yasmin Lima',
 'Natália Oliveira',
 'Dr. Pedro Miguel Almeida',
 'Diogo Almeida',
 'Juliana Correia',
 'Sr. Gustavo Oliveira',
 'Larissa Carvalho',
 'Diego Silva',
 'Cauã Carvalho',
 'Emanuella Lima',
 'Gabrielly Pereira',
 'Cauê Costela',
 'Luiz Gustavo Castro',
 'Kaique Silva',
 'Benjamin Dias',
 'Kaique Gomes',
 'Helena Fernandes',
 'Srta. Ana Silva',
 'Pietra Gomes',
 'Dr. Davi Castro',
 'Isaac Gomes',
 'João Lucas Fernandes',
 'Leandro Martins',
 'Luiz Otávio Cunha',
 'Natália Dias',
 'Dra. Alexia Fernandes',
 'Calebe Barbosa',
 'Cauã Santos',
 'Nathan Silva',
 'Dr. Nathan Santos',
 'Sofia Ferreira',
 'Caroline Rocha',
 'Emanuella Dias',
 'Sofia Oliveira',
 'Yago Barbosa',
 'Dr. Vinicius Alves',
 'Ana Lívia Correia',
 'Raul Azevedo',
 'Bruno Santos',
 'Sra. Marcela Alves',
 'Lucas Almeida',
 'Heloísa Santos',
 'Samuel Gomes',
 'Sr. Joaquim Santos',
 'Maria Cecília Pereira',
 'Emanuelly Carvalho',
 'Sr. Davi Lucca Melo',
 'Luiz Fernando Rodrigues',
 'Srta. Valentina Ferreira',
 'Srta. Bruna Almeida',
 'Brenda Almeida',
 'Dr. Felipe Araújo',
 'Srta. Isadora Alves',
 'Dr. Pedro Miguel Ferreira',
 'Maria Cecília Cunha',
 'Carolina Fernandes',
 'Dr. Levi Barros',
 'Enzo Cunha',
 'Srta. Lorena Rocha',
 'Davi Lucas Gomes',
 'Marcelo Azevedo',
 'Srta. Joana Pereira',
 'Giovanna Castro',
 'Isabella Correia',
 'Emilly Azevedo',
 'Maria Eduarda Melo',
 'Letícia Araújo',
 'Lucca Cunha',
 'Isadora Lima',
 'Augusto Pereira',
 'Pedro Miguel Alves',
 'João Felipe Castro',
 'Augusto Oliveira',
 'Brenda Cunha',
 'Henrique Fernandes',
 'Maria Fernanda Araújo',
 'Lucas Gabriel Lima',
 'Vicente Silva',
 'Sofia Martins',
 'Dra. Lívia Cardoso',
 'Dr. Antonio Santos',
 'Ian Almeida',
 'Sr. Kaique Carvalho',
 'Ian Castro',
 'Sr. Rafael Alves',
 'Vitor Oliveira',
 'Dr. Murilo Gomes',
 'Maria Fernanda Barros',
 'Carolina Carvalho',
 'Bárbara Correia',
 'Mariane Rocha',
 'Henrique Dias',
 'Cauê Martins',
 'Luigi Ribeiro',
 'Igor Rodrigues',
 'Nathan Ribeiro',
 'Srta. Ana Laura Castro',
 'Dra. Ana Sophia Santos',
 'Dra. Bianca Castro',
 'Maitê Castro',
 'Alana Araújo',
 'Leonardo Ribeiro',
 'Dr. Gustavo Henrique Barbosa',
 'Srta. Alana Fernandes',
 'Sra. Luana Rocha',
 'Augusto Azevedo',
 'Mariana Rocha',
 'Sr. Pedro Miguel Cunha',
 'Lorenzo Rocha',
 'Lucas Barros',
 'Anthony Carvalho',
 'Sr. Noah Gomes',
 'Helena Dias',
 'Stella Rocha',
 'Amanda Correia',
 'Levi Santos',
 'Evelyn Santos',
 'Sr. Erick Fernandes',
 'Ryan Rodrigues',
 'Evelyn Ribeiro',
 'Breno Santos',
 'Maria Clara Souza',
 'Sr. Enzo Gabriel Souza',
 'Eduardo Cunha',
 'Gabrielly Carvalho',
 'Ana Carolina Melo',
 'Julia Alves',
 'Ana Vitória Cardoso',
 'Danilo Pinto',
 'Emanuella Rocha',
 'Nina Almeida',
 'Luiz Miguel Castro',
 'Sabrina Alves',
 'Yuri Castro',
 'Sr. Yuri Costela',
 'Sr. Nathan Rocha',
 'Lucas Gabriel Cunha',
 'Isabella Carvalho',
 'Kamilly Pinto',
 'Eloah Ferreira',
 'João Lucas Correia',
 'Erick Pinto',
 'Amanda Oliveira',
 'Pedro Lucas Oliveira',
 'Isadora Rodrigues',
 'Camila Rodrigues',
 'Pedro Henrique Melo',
 'Bianca Correia',
 'Paulo Barbosa',
 'Diego Ribeiro',
 'Luiz Henrique Fernandes',
 'Sra. Esther Gomes',
 'Lorena Melo',
 'Bárbara Melo',
 'Sr. Antonio Costela',
 'Ana Sophia Melo',
 'Maria Vitória Lima',
 'Dr. Antonio Ribeiro',
 'Kevin Lima',
 'Isabelly Dias',
 'Paulo Cardoso',
 'Juan Alves',
 'Sr. Nathan Pereira',
 'Nathan Araújo',
 'Pedro Henrique Dias',
 'Erick Fernandes',
 'Dr. Luiz Gustavo Pereira',
 'Dr. Noah Araújo',
 'Fernando Costela',
 'Srta. Esther Alves',
 'Sr. Vinicius Gomes',
 'Pedro Miguel Pinto',
 'Samuel Pereira',
 'Francisco Fernandes',
 'Maria Almeida',
 'Natália Almeida',
 'Sra. Ana Lima',
 'Catarina Ribeiro',
 'Marina Cardoso',
 'Juan Silva',
 'Paulo Barros',
 'Natália Ribeiro',
 'Dra. Helena Ferreira',
 'Pedro Henrique Cardoso',
 'Alana Silva',
 'Camila Costela',
 'Nicole Azevedo',
 'Ana Vitória Gomes',
 'Srta. Heloísa Costela',
 'Raquel Alves',
 'Dr. Vitor Hugo Dias',
 'Marcelo Carvalho',
 'Samuel Fernandes',
 'Miguel Souza',
 'Thales Araújo',
 'Rafaela Martins',
 'Srta. Agatha Silva',
 'João Felipe Barbosa',
 'Marcela Dias',
 'Olivia Azevedo',
 'Sr. Murilo Azevedo',
 'Ryan Oliveira',
 'André Dias',
 'Valentina Cardoso',
 'Emanuelly Gomes',
 'Dra. Luana Pereira',
 'Valentina Carvalho',
 'Dra. Marina Souza',
 'Lucca Gomes',
 'Bryan Santos',
 'Srta. Valentina Fernandes',
 'Sr. Benício Lima',
 'Cauê Barbosa',
 'Valentina Silva',
 'Ana Julia Carvalho',
 'Emanuel Pereira',
 'Vinicius Santos',
 'Joana Martins',
 'Nathan Barbosa',
 'Cecília Cardoso',
 'Dr. Davi Pereira',
 'Augusto Costela',
 'Dra. Camila Barbosa',
 'Larissa Lima',
 'Thomas Rocha',
 'Sr. Vitor Rocha',
 'Helena Pereira',
 'André Cardoso',
 'Maria Cecília Alves',
 'Maria Cecília Melo',
 'Srta. Sarah Gomes',
 'Maria Fernanda Cunha',
 'Laura Melo',
 'Enzo Fernandes',
 'Bruno Cardoso',
 'Yuri Lima',
 'Benjamin Oliveira',
 'Ana Julia Araújo',
 'Rodrigo Pereira',
 'Mariane Carvalho',
 'Benício Barros',
 'Dr. Juan Carvalho',
 'Dra. Lorena Oliveira',
 'Srta. Maria Clara Cunha',
 'Marina Melo',
 'Dra. Isabella Silva',
 'Luana Costela',
 'Amanda Ribeiro',
 'Igor Ribeiro',
 'Samuel Souza',
 'Alice Pinto',
 'Luiz Gustavo Pinto',
 'Carlos Eduardo Dias',
 'Clarice Lima',
 'Nicolas Cunha',
 'Dr. Danilo Cardoso',
 'Maria Julia Barros',
 'Srta. Ana Ribeiro',
 'Sra. Marina Castro',
 'Theo Pinto',
 'Sr. Henrique Castro',
 'Miguel Castro',
 'Sra. Emanuelly Pinto',
 'Cauê Souza',
 'Paulo Rocha',
 'Esther Almeida',
 'Calebe Rocha',
 'Arthur Barbosa',
 'Dra. Eloah Cardoso',
 'Fernando Silva',
 'Sra. Isabella Martins',
 'Samuel Correia',
 'Yasmin Ribeiro',
 'Luiz Henrique Gomes',
 'Theo Santos',
 'Rodrigo Cardoso',
 'Danilo Cunha',
 'João Lucas Carvalho',
 'Danilo Fernandes',
 'João Miguel Correia',
 'Joana Melo',
 'Isabel Lima',
 'Marina Almeida',
 'Srta. Luna Rodrigues',
 'Maria Clara Ribeiro',
 'Srta. Maria Luiza Martins',
 'Sr. Paulo Gomes',
 'Dr. Theo Ribeiro',
 'Nicole Correia',
 'Cauã Ferreira',
 'Francisco Costela',
 'Maria Sophia Oliveira',
 'Helena Cardoso',
 'Leonardo Ferreira',
 'Sr. Vitor Ferreira',
 'Caio Cunha',
 'Antonio Carvalho',
 'Gustavo Henrique Martins',
 'Vitor Hugo Almeida',
 'Sra. Lívia Azevedo',
 'Luiz Felipe Souza',
 'Pietra Pereira',
 'Dr. Felipe Barbosa',
 'Yago Gomes',
 'Anthony Barbosa',
 'Eloah Rocha',
 'Sr. Henrique Gomes',
 'Sarah Martins',
 'Dra. Daniela Lima',
 'Antonio Melo',
 'Sr. Yuri Lima',
 'Kevin Rocha',
 'Milena Costela',
 'Lucca Alves',
 'Gustavo Martins',
 'Thiago Carvalho',
 'Francisco Melo',
 'Sr. Fernando Melo',
 'Sr. Luiz Henrique Pinto',
 'Sra. Maria Sophia Alves',
 'Erick Alves',
 'Lara Gomes',
 ...}

Agora vamos supor que temos uma lista de nomes e queremos conferir se eles estão no conjunto de nomes. Normalmente faríamos:


In [51]:
buscas = {'João Silva', 'Ana Ferreira', 'Eduardo Santos', 'Pedro Alves', 'Enzo Correira'}

presentes = [busca for busca in buscas if busca in nomes]
presentes


Out[51]:
['Ana Ferreira', 'Eduardo Santos']

In [52]:
ausentes = [busca for busca in buscas if busca not in nomes]
ausentes


Out[52]:
['João Silva', 'Enzo Correira', 'Pedro Alves']

Porém se usarmos operações de conjunto podemos fazer isso de forma mais simples e eficiente.

Para saber quais nomes buscados estão no conjunto de nomes:


In [53]:
buscas & nomes


Out[53]:
{'Ana Ferreira', 'Eduardo Santos'}

Os nomes que não estão:


In [54]:
buscas - nomes


Out[54]:
{'Enzo Correira', 'João Silva', 'Pedro Alves'}

Comparando o tempo de execução das buscas usando for contra buscas usando intersecção obtemos o seguinte resultado:


In [55]:
# tamanho  | tempo set + for | tempo set + & | for vs &
# 100      | 3.945e-05       | 1.86e-06      | & é 21.25x + rápido
# 1000     | 5.844e-05       | 1.751e-05     | & é 3.34x + rápido
# 10000    | 0.00014848      | 5.991e-05     | & é 2.48x + rápido
# 100000   | 0.00015138      | 8.862e-05     | & é 1.71x + rápido
# 1000000  | 0.00014647      | 8.113e-05     | & é 1.81x + rápido

dict

Dict, dictnionary ou dicionário é a estrutura padrão de mapeamento e é indexado por chaves compostas por tipos imutáveis (números, strings, tuplas etc.).

Já falamos sobre dicionários anteriormente, nesta aula faremos uma rápida revisão e aprofundremos mais sobre o assunto:


In [56]:
votos = {'joão': 10, 'maria': 25, 'ana': 40, 'pedro': 75}
votos['joão']


Out[56]:
10

In [57]:
votos['joão'] = 11
votos


Out[57]:
{'ana': 40, 'joão': 11, 'maria': 25, 'pedro': 75}

Como podem ver aqui os dicionários não mantém a ordem de seus elementos. Criamos o dict com os elementos {'joão': 10, 'maria': 25, 'ana': 40, 'pedro': 75}, porém sua ordem atual é {'ana': 40, 'joão': 11, 'maria': 25, 'pedro': 75} e, futuramente, essa ordem pode ser outra conforme alteramos esse dicionário.


In [58]:
len(votos)


Out[58]:
4

In [59]:
del votos['joão']
votos


Out[59]:
{'ana': 40, 'maria': 25, 'pedro': 75}

Vale notar que ao tentar acessar um elemento não existente é levantada uma exceção:


In [60]:
votos['joão']


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-60-5818ac2b3445> in <module>()
----> 1 votos['joão']

KeyError: 'joão'

As vezes pode ser necessário evitar esse tipo de comportamento. Isso pode ser feito usando a função:


In [61]:
print(votos.get('joão'))


None

também é possível estabelecer um valor para ser retornado caso a chave não seja encontrada:


In [62]:
votos.get('joão', 0)


Out[62]:
0

Por exemplo se você quiser contabilizar os votos de uma eleição em que nem todos os candidatos receberam votos e, portanto, não aparecem no dicionário votos:


In [63]:
candidatos = list(votos.keys()) + ['joão', 'muriel', 'marcola']
candidatos


Out[63]:
['maria', 'ana', 'pedro', 'joão', 'muriel', 'marcola']

In [64]:
for candidato in candidatos:
    print('{} recebeu {} votos.'.format(candidato, votos.get(candidato, 0)))


maria recebeu 25 votos.
ana recebeu 40 votos.
pedro recebeu 75 votos.
joão recebeu 0 votos.
muriel recebeu 0 votos.
marcola recebeu 0 votos.

Podemos verificar se alguma chave existe no dicionário com o in:


In [65]:
votos


Out[65]:
{'ana': 40, 'maria': 25, 'pedro': 75}

In [66]:
'ana' in votos


Out[66]:
True

In [67]:
'penélope' in votos


Out[67]:
False

In [68]:
len(votos)  # número de items no dict


Out[68]:
3

In [69]:
outros_votos = {'milena': 100, 'mário': 1}
votos.update(outros_votos)  # atualiza o dicionário votos com os items de outros_votos
votos


Out[69]:
{'ana': 40, 'maria': 25, 'milena': 100, 'mário': 1, 'pedro': 75}

Para acessar somente as chaves de um dicionário fazemos:


In [70]:
votos.keys()


Out[70]:
dict_keys(['ana', 'maria', 'milena', 'mário', 'pedro'])

Percebe-se que o retorno não é uma lista de chaves, mas sim um dict_keys. Não vou entrar em detalhes, mas esse dict_keys - junto com dict_values e dict_items que serão mostrados mais a frente - se comportam como conjunto, por tanto verificações de pertencimento são muito eficientes, além de suportar algumas operações de conjuntos:

Para mais informações verifique a documentação oficial e o PEP 3106 em que essa mudança foi proposta


In [71]:
['maria', 'adelaide'] & votos.keys()


Out[71]:
{'maria'}

In [72]:
['maria', 'adelaide'] - votos.keys()


Out[72]:
{'adelaide'}

Para acessar somente os valores do dicionários:


In [73]:
votos.values()


Out[73]:
dict_values([40, 25, 100, 1, 75])

Como os valores não são únicos o dict_values não pode se comportar como conjunto, por esse motivo ele não possui as operações de conjuntos


In [74]:
votos.items()


Out[74]:
dict_items([('ana', 40), ('maria', 25), ('milena', 100), ('mário', 1), ('pedro', 75)])

Porém o dict.items() implementa as operações de conjuntos, pois a dupla chave e valor são únicas:


In [75]:
[('jean', 50), ('maria', 25)] & votos.items()


Out[75]:
{('maria', 25)}

In [76]:
[('jean', 50), ('maria', 25)] - votos.items()


Out[76]:
{('jean', 50)}

Revendo iteração de dicionários:


In [77]:
for nome in votos.keys():
    print(nome)


ana
maria
milena
mário
pedro

In [78]:
for qtd_votos in votos.values():
    print(qtd_votos)


40
25
100
1
75

In [79]:
for nome, qtd_votos in votos.items():  # atribuição múltipla, lembra?
    print('{} recebeu {} votos.'.format(nome.capitalize(), qtd_votos))


Ana recebeu 40 votos.
Maria recebeu 25 votos.
Milena recebeu 100 votos.
Mário recebeu 1 votos.
Pedro recebeu 75 votos.

Exercício

  • Calcule a média de votos por candidatos:

In [5]:
# não mude esse código, ele que gera os votos para você testar seu programa

from faker import Factory
import random

factory = Factory.create('pt_BR')

# usa distribuição de gauss para gerar quantidade de votos
votos = {factory.name(): abs(round(random.gauss(0, .2) * 10000)) for _ in range(333)}
# deixa nomes completos com somente dois nomes
votos = {nome: votos for nome, votos in votos.items() if len(nome.split()) == 2}

In [ ]:
def media(votos):
    ...

Assim como listas e sets, dicionários também possuem uma maneira de criar dicts com facilidade: dict comprehension


In [82]:
from faker import Factory

factory = Factory.create('pt_BR')
cpfs = {factory.name(): factory.cpf() for _ in range(10)}
cpfs


Out[82]:
{'Amanda Barros': '092.546.137-71',
 'Dr. João Azevedo': '453.168.209-24',
 'Emanuella Ferreira': '210.796.483-13',
 'João Felipe Melo': '103.647.825-44',
 'João Felipe Oliveira': '965.731.428-37',
 'Maysa Dias': '912.638.507-41',
 'Nicole Souza': '532.496.078-19',
 'Srta. Brenda Costela': '264.519.038-33',
 'Stephany Rocha': '843.076.159-48',
 'Vitória Souza': '315.698.240-71'}

In [83]:
{numero: numero ** 2 for numero in range(10)}


Out[83]:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Acontece que dict comprehension nos dá uma maneira muito bonilinda de inverter as chaves e valores de dicionários:


In [84]:
telefones = {'joão': '9941', 'ana': '9103', 'maria': '9301', 'pedro': '9203'}
telefones


Out[84]:
{'ana': '9103', 'joão': '9941', 'maria': '9301', 'pedro': '9203'}

Normalmente faríamos:


In [85]:
nomes = {}
for nome, telefone in telefones.items():
    nomes[telefone] = nome
    
nomes


Out[85]:
{'9103': 'ana', '9203': 'pedro', '9301': 'maria', '9941': 'joão'}

Mas com dict comprehension é muito mais fácil:


In [86]:
{telefone: nome for nome, telefone in telefones.items()}


Out[86]:
{'9103': 'ana', '9203': 'pedro', '9301': 'maria', '9941': 'joão'}

Ordenando um dict pelas chaves:


In [87]:
sorted(telefones.items())


Out[87]:
[('ana', '9103'), ('joão', '9941'), ('maria', '9301'), ('pedro', '9203')]

Não faz snetido obter dict pq dict nào mantém a ordem.

Para ter um objeto do tipo dict é necessário converter o código acima:


In [88]:
dict(sorted(telefones.items()))


Out[88]:
{'ana': '9103', 'joão': '9941', 'maria': '9301', 'pedro': '9203'}

Para ordernar pelos valores precisamos "avisar" a função sorted() para usar o valor como a chave. Isso é feito passando um argumento key que recebe uma função que é usada para pegar o valor que será usado na ordenação. Nesse caso precisamos criar uma função que retorna o segundo elemento de nossa lista de tuplas chave e valor, referente a esse último.


In [89]:
def pega_segundo_elemento(tupla):
    return tupla[1]

sorted(telefones.items(), key=pega_segundo_elemento)


Out[89]:
[('ana', '9103'), ('pedro', '9203'), ('maria', '9301'), ('joão', '9941')]

Adendo: no Python funções são objetos de primeira classe. Isso signfica que funções, assim como inteiros, strings e listas, podemos passá-las como parâmetros, atribuí-las a variáveis e outras operações. Esse assunto será abordando com maior profundidade na aula sobre funções.

Um outro jeito comum de realizar essa ordenação é usar funções anônimas:


In [90]:
pega_segundo_elemento = lambda x: x[1]

sorted(telefones.items(), key=pega_segundo_elemento)


Out[90]:
[('ana', '9103'), ('pedro', '9203'), ('maria', '9301'), ('joão', '9941')]

Geralmente o uso de funções anônimas é feito assim:


In [91]:
sorted(telefones.items(), key=lambda x: x[1])


Out[91]:
[('ana', '9103'), ('pedro', '9203'), ('maria', '9301'), ('joão', '9941')]

Porém, o jeito mais eficiente de realizar esse tipo de operação é utilizando a biblioteca operator que implementa os operadores do python de forma eficiente:


In [92]:
from operator import itemgetter

sorted(telefones.items(), key=itemgetter(1))


Out[92]:
[('ana', '9103'), ('pedro', '9203'), ('maria', '9301'), ('joão', '9941')]

A função itemgetter() da biblioteca operator faz o mesmo que a função pega_segundo_elemento() mas de forma muito mais rápida. Para saber mais sobre operator veja sua documentação.

Exemplos

Dicionários podem ser utilizados para armazenar matrizes esparsas

Exercícios

  • Dado uma frase calcule as ocorrências de cada palavra naquela. Armazene cada palavra como chave em um dict e as quantidade seu valor:

In [17]:
from collections  import defaultdict

def conta_palavras(frase):
    contagem = {}
    ...
    return contagem

In [16]:
# rode o código abaixo para testar a corretude de seu programa

assert conta_palavras("quod dolore dolore dolore modi sapiente quod ullam nostrum ullam") == {'ullam': 2, 'sapiente': 1, 'quod': 2, 'nostrum': 1, 'dolore': 3, 'modi': 1}
assert conta_palavras("soluta Soluta sapiente sapiente nostrum Sapiente dolore nostrum modi ullam") == {'ullam': 1, 'sapiente': 3, 'nostrum': 2, 'dolore': 1, 'soluta': 2, 'modi': 1}
assert conta_palavras("quod dolore dolore soluta sapiente sapiente dolore quod sapiente modi") == {'dolore': 3, 'quod': 2, 'soluta': 1, 'modi': 1, 'sapiente': 3}
assert conta_palavras("dolore Dolore quis quod dolore nostrum quod Nostrum sapiente soluta") == {'sapiente': 1, 'quod': 2, 'nostrum': 2, 'soluta': 1, 'dolore': 3, 'quis': 1}
assert conta_palavras("sapiente sapiente quod soluta quis ullam nostrum soluta ullam ullam") == {'ullam': 3, 'sapiente': 2, 'quod': 1, 'nostrum': 1, 'soluta': 2, 'quis': 1}
assert conta_palavras("modi Sapiente dolore Soluta sapiente quis soluta modi dolore ullam") == {'ullam': 1, 'sapiente': 2, 'quis': 1, 'dolore': 2, 'soluta': 2, 'modi': 2}
assert conta_palavras("quis quis nostrum nostrum sapiente quis nostrum quod quis dolore") == {'sapiente': 1, 'quod': 1, 'quis': 4, 'nostrum': 3, 'dolore': 1}
assert conta_palavras("nostrum sapiente quis ullam ullam quod ullam nostrum ullam soluta") == {'ullam': 4, 'sapiente': 1, 'quod': 1, 'nostrum': 2, 'soluta': 1, 'quis': 1}
assert conta_palavras("sapiente ullam quod quis dolore modi Quis quod dolore nostrum") == {'ullam': 1, 'sapiente': 1, 'quod': 2, 'quis': 2, 'nostrum': 1, 'dolore': 2, 'modi': 1}
assert conta_palavras("modi nostrum ullam Quis Soluta modi quis ullam modi ullam") == {'ullam': 3, 'soluta': 1, 'modi': 3, 'nostrum': 1, 'quis': 2}
  • Escreva uma função comprime_chaves_dict() que receba um dict e remova as vogais das chaves de um dicionário. Por exempo o dict {'foo': 10, 'bar': 100} deve ser comprimido para {'f': 10, 'br': 100}.

In [ ]:
def comprime_chaves_dict(dicionario):
    ...

In [29]:
assert comprime_chaves_dict({'molestias': 3950, 'tempore': 'possimus', 'rerum': 1200}) == {'tmpr': 'possimus', 'mlsts': 3950, 'rrm': 1200}
assert comprime_chaves_dict({'nam': 5300, 'minus': 3700, 'fugit': 8600}) == {'mns': 3700, 'nm': 5300, 'fgt': 8600}
assert comprime_chaves_dict({'magnam': 2850, 'quam': 2300, 'asperiores': 7750}) == {'qm': 2300, 'sprrs': 7750, 'mgnm': 2850}
assert comprime_chaves_dict({'quos': 'dignissimos', 'qui': 1700, 'repellendus': 'aut'}) == {'rpllnds': 'aut', 'q': 1700, 'qs': 'dignissimos'}
assert comprime_chaves_dict({'quaerat': 9850, 'magni': 8600, 'blanditiis': 'optio'}) == {'mgn': 8600, 'qrt': 9850, 'blndts': 'optio'}

Fim da aula 04