Conjuntos e dicionários

Escolher estruturas para pertença, operações de conjuntos e contagens por chave.

Perguntar sobre esta página

ChatGPTClaudePerplexityGeminiCopiar e abrir

Brain rot

A seguirPara ti

@resumos.feup

som original ·

Definições

Leitura

Mudar de trecho
Legendas
Mostrar no vídeo
Vídeos de fundo

O texto, o áudio e os teus vídeos ficam neste dispositivo.

Créditos dos vídeos e da voz

Partilhar página

Uma lista responde à pergunta “o que está na posição 2?”. Um conjunto responde “este valor está presente?”. Um dicionário responde “qual é o valor associado a esta chave?”. Escolhe a estrutura pela operação de que precisas.

Conjuntos sem repetições

set guarda elementos distintos. {1, 2, 2} tem apenas 1 e 2. Não indexas um conjunto e não deves depender da ordem em que os seus valores aparecem. O conjunto vazio é set(); {} cria um dicionário vazio.

OperaçãoEscritaSignificado
Uniãoa | bEstá em pelo menos um
Interseçãoa & bEstá nos dois
Diferençaa - bEstá em a e não em b
Diferença simétricaa ^ bEstá em exatamente um
Inclusãoa <= bTodos os elementos de a estão em b

Se a = {"Porto", "Braga"} e b = {"Porto", "Aveiro"}, a interseção é {"Porto"}. A diferença a - b é {"Braga"}. A direção da diferença faz parte do resultado.

add(x) acrescenta um elemento. discard(x) retira-o se existir. remove(x) exige que exista e lança KeyError caso contrário. Usa sorted(conjunto) para obter uma lista numa ordem reprodutível.

Chaves de um dicionário

precos = {"pão": 1.5, "leite": 1.2}
print(precos["pão"])

A chave "pão" identifica um valor, 1.5. Uma chave repetida recebe o último valor atribuído. "pão" in precos testa as chaves, não os preços. precos["arroz"] lança KeyError; precos.get("arroz", 0) devolve zero quando não encontra a chave.

O zero por defeito só é adequado quando significa realmente “não havia unidades contadas” ou outra convenção declarada. Não uses zero para esconder um preço desconhecido.

As chaves e os elementos dos conjuntos têm de ser hashable, ou seja, suportar uma identidade de dispersão estável usada na procura. Inteiros, strings e tuplos de valores hashable servem. Listas e dicionários não servem. Um tuplo que contém uma lista também não serve como chave.

Contar ocorrências

Vamos contar vendas por produto. Para cada produto, lemos a contagem anterior, usando zero quando aparece pela primeira vez, e somamos um.

Contar e deduplicar
vendas = ["pão", "leite", "pão", "arroz", "leite", "pão"]
contagens = {}
for produto in vendas:
    contagens[produto] = contagens.get(produto, 0) + 1
for produto, quantidade in contagens.items():
    print(produto, quantidade)
print(sorted(set(vendas)))
Dados de entrada

As contagens são pão 3, leite 2 e arroz 1. O conjunto conserva apenas os nomes distintos. Os dicionários conservam a ordem de inserção das chaves em Python atual, mas a contagem não depende dessa ordem.

keys() percorre chaves, values() percorre valores e items() percorre pares chave-valor. Em for produto, quantidade in contagens.items(), o par de cada iteração é desempacotado nos dois nomes.

Alterar um dicionário e interpretar o retorno

OperaçãoEfeito e retorno
d.pop(chave)Remove e devolve o valor; KeyError se faltar
d.pop(chave, valor_padrao)Devolve o padrão se a chave faltar
del d[chave]Remove sem devolver o valor; KeyError se faltar
d.popitem()Remove e devolve o último par inserido; KeyError se vazio
d.setdefault(chave, valor)Devolve o valor existente ou insere e devolve o padrão
d.update(outro)Acrescenta ou substitui pares; devolve None
d.clear()Esvazia o dicionário; devolve None
d.copy()Devolve uma cópia superficial
dict.fromkeys(chaves, valor)Cria chaves associadas ao mesmo objeto de valor

get lê sem inserir; setdefault pode inserir. update substitui valores de chaves existentes e acrescenta chaves novas. Não atribuas o retorno de update ao dicionário, porque esse retorno é None.

stock = {"A": 2}
chaves = stock.keys()
print(stock.setdefault("A", 9))  # 2, sem substituir
stock.setdefault("B", 4)
stock.update({"A": 3})
print(list(chaves))               # ['A', 'B']
print(stock.popitem())            # ('B', 4)
print(list(chaves))               # ['A']

Em Python atual, keys, items e values devolvem vistas, que refletem alterações ao dicionário, e não listas independentes. Usa list(...) para guardar uma sequência do estado naquele momento. Evita acrescentar ou remover chaves enquanto percorres a vista.

dict.fromkeys(["A", "B"], []) partilha a mesma lista entre os dois valores. Para listas independentes, usa {chave: [] for chave in ["A", "B"]}. Uma cópia superficial de um dicionário também continua a partilhar objetos mutáveis guardados como valores.

Escolher a estrutura

Precisas de…Estrutura
Conservar a ordem e as repetições das vendasLista
Guardar um par fixo de coordenadasTuplo
Saber que produtos apareceram pelo menos uma vezConjunto
Associar cada produto ao seu preçoDicionário

Converter uma lista para conjunto perde repetições e a ordem original. Não é uma operação neutra. Se cada ocorrência representar uma venda, essa conversão já não preserva o número de vendas.

Exercícios

Escolher a direção da diferença

a = 4 e b = 5. Quantos elementos tem a - b?

Primeira pista
Retira de a os valores que também estão em b.
Mais uma pista
Restam 1 e 2.
Ver solução
Há dois elementos. b - a seria o conjunto com 5 e teria um elemento.

Erros frequentes

Usar a união ou ignorar que a direção da diferença muda o resultado.
Voltar à explicação
Contar sem perder ocorrências

Escreve contagens(valores), que devolve um dicionário de frequências. O resultado para a, b, a deve ser a: 2 e b: 1. Para lista vazia, devolve dicionário vazio.

Contar sem perder ocorrências
def contagens(valores):
    return {}

assert contagens([]) == {}
assert contagens(["a", "b", "a"]) == {"a": 2, "b": 1}
assert contagens([3, 3, 3]) == {3: 3}
print("Casos verificados")
Dados de entrada

Primeira pista
Cada valor é uma chave.
Mais uma pista
Usa resultado.get(valor, 0) + 1 em cada iteração.
Ver solução

Cria um dicionário vazio, percorre os valores e atualiza a contagem da chave. Devolve o dicionário no fim do ciclo.

Confere a tua resposta:

  • Contei cada ocorrência sem converter a entrada em conjunto.
  • Tratei a primeira ocorrência com contagem inicial zero.
  • Passei os casos vazio e repetido.

Erros frequentes

Usar um conjunto perde repetições; colocar return dentro do ciclo interrompe na primeira ocorrência.

Voltar à explicação
Ler ou inserir sem substituir

stock = {"A": 2}; resultado = stock.setdefault("A", 9). Quanto vale resultado?

Primeira pista
A chave A já existe.
Mais uma pista

O valor por defeito só é inserido quando a chave está ausente.

Ver solução

Devolve 2 e stock conserva a chave A associada a 2. A chamada não substitui um valor existente.

Erros frequentes

Confundir setdefault com uma atribuição explícita ou com update.

Voltar à explicação

À tua maneira

Aparência

Modo de cor
Tema
Cor de destaque

Leitura

Fonte de leitura

Álgebra, lógica e uma ideia de cada vez.

Código

Fonte do código

CSS personalizado

Ativa uma sugestão ou guarda o teu CSS. Só muda este navegador.

Usa --page, --text e --accent para acompanhar o tema.

Seletores e recuperação

.site-header, .prose, .course-card, [data-reading-history], [data-playground] e .page-actions.

Abre a aparência com a tecla vírgula ou no rodapé. Se o CSS esconder os controlos, abre esta página sem CSS personalizado.

Pesquisar

Escreve para pesquisar em todo o site.

para escolher · Enter para abrir · Esc para fechar

Atalhos de teclado

Clica numa tecla para a mudar. Esc cancela. Backspace desativa.

PesquisarCtrl / Cmd K

Os atalhos não interferem enquanto escreves. Tab e Enter funcionam sempre.