🌗 ← Índice

🐍 Python P05 — Dicionários e Tuplas


Data: 19/06/2026

Nível: Básico




Dicionários e tuplas são estruturas de dados fundamentais em Python. Dicionários organizam informações por chave-valor (como um cardápio com nome → preço), enquanto tuplas armazenam sequências imutáveis (como coordenadas ou horários fixos). Dominar essas duas estruturas é essencial para qualquer programa Python real.




O que vamos aprender


  • Dicionários (`dict`) — criar, acessar e modificar pares chave-valor
  • Métodos essenciais: `.get()`, `.keys()`, `.values()`, `.items()`
  • Tuplas (`tuple`) — imutabilidade, unpacking e quando usar
  • `zip()` — combinar listas em dicionários
  • `enumerate()` — revisão aplicada a dicionários
  • Dict comprehension — criar dicionários de forma concisa
  • Exemplo prático: cardápio de serviços com preços
  • Exemplo prático: agenda de horários com tuplas



  • 📌 Dicionários (`dict`) — Chave e Valor


    Um dicionário é uma coleção de pares chave: valor. Pense nele como uma tabela onde cada chave (única) tem um valor associado. Em Python, a sintaxe usa {} (chaves).


    Doc oficial: [docs.python.org — Dictionaries](https://docs.python.org/3/tutorial/datastructures.html#dictionaries)


    
    # Criando um dicionário — cardápio da barbearia
    servicos = {
        "Corte": 70,
        "Barba": 40,
        "Corte + Barba": 110,
        "Hidratação": 60,
        "Sobrancelha": 25
    }
    

    Acessando valores


    
    # Acesso direto pela chave
    print(servicos["Corte"])        # 70
    print(servicos["Barba"])        # 40
    
    # CUIDADO: se a chave não existir, dá KeyError!
    # print(servicos["Manicure"])   # ❌ KeyError: 'Manicure'
    

    
    # .get() — acesso seguro (sem KeyError)
    print(servicos.get("Corte"))           # 70
    print(servicos.get("Manicure"))        # None (chave não existe)
    print(servicos.get("Manicure", 0))     # 0 (valor padrão se não existir)
    

    ▶ Saída:

    
    70
    None
    0
    

    💡 Prefira .get() com valor padrão — principalmente ao receber dados de formulários ou APIs, onde a chave pode não existir.


    Adicionando e modificando itens


    
    # Adicionar novo serviço
    servicos["Pezinho"] = 35
    print(servicos["Pezinho"])      # 35
    
    # Modificar um existente
    servicos["Corte"] = 75          # Aumento de preço!
    print(servicos["Corte"])        # 75
    
    # Remover com del
    del servicos["Sobrancelha"]
    

    Métodos essenciais: .keys(), .values(), .items()


    
    servicos = {"Corte": 75, "Barba": 40, "Hidratação": 60}
    
    # .keys() — todas as chaves
    print(list(servicos.keys()))    # ['Corte', 'Barba', 'Hidratação']
    
    # .values() — todos os valores
    print(list(servicos.values()))  # [75, 40, 60]
    
    # .items() — pares (chave, valor) — ÓTIMO para loops!
    for servico, preco in servicos.items():
        print(f"✂️ {servico}: R$ {preco:.2f}")
    

    ▶ Saída:

    
    ['Corte', 'Barba', 'Hidratação']
    [75, 40, 60]
    ✂️ Corte: R$ 75.00
    ✂️ Barba: R$ 40.00
    ✂️ Hidratação: R$ 60.00
    

    💡 .items() é o método mais usado com dicionários. Ele retorna uma view (visão) que você pode iterar perfeitamente com for chave, valor in dict.items().




    📌 Tuplas (`tuple`) — Imutável e Confiável


    Uma tupla é como uma lista, mas imutável: depois de criada, não pode ser alterada. Use () (parênteses) para criá-la.


    Doc oficial: [docs.python.org — Tuples and Sequences](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences)


    
    # Criando tuplas
    coordenadas = (10, 20)
    horario = ("14:00", "Hugo", "Corte")
    dias_semana = ("Seg", "Ter", "Qua", "Qui", "Sex", "Sáb")
    
    # Tupla de um elemento — PRECISA da vírgula!
    unico = (42,)     # tupla de 1 elemento ✅
    nao_eh_tupla = (42)  # isso é um int! ❌
    
    # Acessando (igual lista)
    print(horario[0])   # "14:00"
    print(horario[1])   # "Hugo"
    

    Imutabilidade — tentar modificar dá erro


    
    horario = ("14:00", "Hugo", "Corte")
    
    # horario[1] = "Pedro"  # ❌ TypeError: 'tuple' object does not support item assignment
    

    💡 Quando usar tupla em vez de lista? Use tupla para dados que não devem mudar: coordenadas, configurações, chaves compostas, registros de banco. A imutabilidade traz segurança e performance.


    Tuple unpacking — desempacotamento elegante


    
    # Desempacotando uma tupla
    horario = ("14:00", "Hugo", "Corte")
    hora, cliente, servico = horario
    
    print(f"{cliente} às {hora} — {servico}")
    # Hugo às 14:00 — Corte
    

    
    # Troca de valores em uma linha (Python style!)
    a, b = 10, 20
    a, b = b, a         # swap! a=20, b=10
    print(a, b)         # 20 10
    

    ▶ Saída:

    
    20 10
    

    💡 Tuple unpacking é um dos recursos mais elegantes do Python. Use para trocar variáveis, desempacotar retornos de funções e iterar com .items().




    📌 zip() — Combinando listas em dicionários


    zip() junta duas (ou mais) sequências, elemento por elemento, como um zíper. Perfeito para criar dicionários a partir de listas paralelas.


    Doc oficial: [docs.python.org — zip()](https://docs.python.org/3/library/functions.html#zip)


    
    # Duas listas separadas
    nomes = ["Corte", "Barba", "Hidratação"]
    precos = [70, 40, 60]
    
    # Combinando com zip() e convertendo para dict
    cardapio = dict(zip(nomes, precos))
    print(cardapio)
    # {'Corte': 70, 'Barba': 40, 'Hidratação': 60}
    

    
    # Exemplo real: agenda de horários
    horarios = ["09:00", "10:00", "11:00", "14:00"]
    clientes = ["Pedro", "Ana", "Carlos", "Hugo"]
    servicos = ["Barba", "Corte", "Corte+Barba", "Hidratação"]
    
    # Criando uma agenda completa
    agenda = dict(zip(horarios, zip(clientes, servicos)))
    
    for hora, (cliente, servico) in agenda.items():
        print(f"🕐 {hora} | {cliente} | {servico}")
    

    ▶ Saída:

    
    🕐 09:00 | Pedro | Barba
    🕐 10:00 | Ana | Corte
    🕐 11:00 | Carlos | Corte+Barba
    🕐 14:00 | Hugo | Hidratação
    

    💡 zip() é muito usado com dict() para criar mapeamentos rapidamente. Se as listas tiverem tamanhos diferentes, o resultado usa o tamanho da menor.




    📌 enumerate() — Revisão com dicionários


    Vimos enumerate() na P03 com listas. Com dicionários, podemos usá-lo para numerar itens ou criar índices.


    Doc oficial: [docs.python.org — enumerate()](https://docs.python.org/3/library/functions.html#enumerate)


    
    servicos = {"Corte": 75, "Barba": 40, "Hidratação": 60, "Corte+Barba": 110}
    
    # Numerando o cardápio (útil para menu de seleção)
    print("📋 Cardápio:")
    for i, (servico, preco) in enumerate(servicos.items(), start=1):
        print(f"  {i}. {servico} — R$ {preco:.2f}")
    

    ▶ Saída:

    
    📋 Cardápio:
      1. Corte — R$ 75.00
      2. Barba — R$ 40.00
      3. Hidratação — R$ 60.00
      4. Corte+Barba — R$ 110.00
    

    
    # enumerate com dict comprehension — criando índice → serviço
    cardapio_numerado = {i: servico for i, servico in enumerate(servicos, 1)}
    print(cardapio_numerado)
    # {1: 'Corte', 2: 'Barba', 3: 'Hidratação', 4: 'Corte+Barba'}
    



    📌 Dict Comprehension — Criando dicionários de forma concisa


    Assim como list comprehension (visto na P03), Python oferece dict comprehension — uma forma concisa de criar dicionários.


    
    # Sintaxe: {chave: valor for item in iterável}
    
    # Exemplo 1: quadrados
    quadrados = {x: x**2 for x in range(1, 6)}
    print(quadrados)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
    

    
    # Exemplo 2: filtrando com if
    servicos = {"Corte": 75, "Barba": 40, "Hidratação": 60, "Corte+Barba": 110}
    
    # Só serviços acima de R$ 50
    caros = {s: p for s, p in servicos.items() if p > 50}
    print(caros)  # {'Corte': 75, 'Hidratação': 60, 'Corte+Barba': 110}
    

    
    # Exemplo 3: transformando valores
    # Aplicar 10% de desconto em todos os serviços
    com_desconto = {s: p * 0.9 for s, p in servicos.items()}
    print(com_desconto)
    # {'Corte': 67.5, 'Barba': 36.0, 'Hidratação': 54.0, 'Corte+Barba': 99.0}
    

    
    # Exemplo 4: invertendo chave e valor
    preco_para_servico = {p: s for s, p in servicos.items()}
    print(preco_para_servico)
    # {75: 'Corte', 40: 'Barba', 60: 'Hidratação', 110: 'Corte+Barba'}
    

    💡 Dict comprehension é amplamente usado em APIs, processamento de dados e transformações. É a forma mais Pythônica de criar dicionários dinamicamente.




    🏪 Exemplo prático — cardápio interativo


    Vamos construir um sistema completo de cardápio usando dicionários, funções e tudo que aprendemos até agora:


    
    """Cardápio da barbearia Los Michelitos — versão interativa."""
    
    # ── Dicionário de serviços (nome → preço) ──
    servicos = {
        "Corte": 75,
        "Barba": 40,
        "Corte + Barba": 110,
        "Hidratação": 60,
        "Sobrancelha": 25,
        "Pezinho": 35,
    }
    
    
    def exibir_cardapio():
        """Mostra o cardápio numerado com preços."""
        print("\n" + "=" * 30)
        print("🏪 Cardápio Los Michelitos")
        print("=" * 30)
        for i, (servico, preco) in enumerate(servicos.items(), 1):
            print(f"  {i:>2}. {servico:20s} R$ {preco:>6.2f}")
        print("=" * 30)
    
    
    def buscar_por_indice(indice):
        """Busca nome e preço pelo índice do menu (1-based)."""
        # Converte para lista de tuplas para acesso por índice
        itens = list(servicos.items())
        if 1 <= indice <= len(itens):
            return itens[indice - 1]  # Retorna (nome, preço)
        return None
    
    
    def calcular_total_combo(*indices):
        """Calcula o total de vários serviços selecionados por índice.
    
        Args:
            *indices: Índices do menu (1, 2, 3...)
    
        Returns:
            tuple: (lista de serviços, total)
        """
        selecionados = []
        total = 0
        for idx in indices:
            resultado = buscar_por_indice(idx)
            if resultado:
                selecionados.append(resultado[0])
                total += resultado[1]
        return selecionados, total
    
    
    # ── Execução ──
    exibir_cardapio()
    
    # Cliente escolheu os itens 1 (Corte) e 3 (Corte+Barba)
    itens, total = calcular_total_combo(1, 3)
    
    print(f"\n🛒 Itens: {', '.join(itens)}")
    print(f"💰 Total: R$ {total:.2f}")
    

    ▶ Saída:

    
    ==============================
    🏪 Cardápio Los Michelitos
    ==============================
       1. Corte                R$  75.00
       2. Barba                R$  40.00
       3. Corte + Barba        R$ 110.00
       4. Hidratação           R$  60.00
       5. Sobrancelha          R$  25.00
       6. Pezinho              R$  35.00
    ==============================
    
    🛒 Itens: Corte, Corte + Barba
    💰 Total: R$ 185.00
    



    🕐 Exemplo prático — agenda de horários com tuplas


    Tuplas são perfeitas para representar agendamentos, onde cada registro é imutável:


    
    """Agenda de horários da barbearia."""
    
    # Cada agendamento é uma tupla: (horário, cliente, serviço, duração_min)
    agenda = [
        ("09:00", "Pedro", "Barba", 30),
        ("09:30", "Ana", "Corte", 45),
        ("10:15", "Carlos", "Corte + Barba", 60),
        ("11:15", "Hugo", "Hidratação", 40),
        ("14:00", "Marina", "Sobrancelha", 20),
        ("14:20", "João", "Corte", 45),
    ]
    
    
    def exibir_agenda(agendamentos):
        """Exibe a agenda formatada."""
        print("\n" + "=" * 55)
        print("📅 Agenda do Dia — Los Michelitos")
        print("=" * 55)
        for horario, cliente, servico, duracao in agendamentos:
            print(f"  🕐 {horario} | {cliente:10s} | {servico:20s} | {duracao} min")
        print("=" * 55)
    
    
    def total_horas_agendadas(agendamentos):
        """Calcula o total de horas agendadas no dia."""
        total_minutos = sum(duracao for _, _, _, duracao in agendamentos)
        return total_minutos / 60
    
    
    def proximo_horario_livre(agendamentos):
        """Encontra o próximo horário livre após o último agendamento."""
        if not agendamentos:
            return "08:00"
    
        # Pega o último agendamento
        ultimo_hora, ultimo_min = agendamentos[-1][0].split(":")
        ultimo_minutos = int(ultimo_hora) * 60 + int(ultimo_min) + agendamentos[-1][3]
    
        hora = ultimo_minutos // 60
        minuto = ultimo_minutos % 60
        return f"{hora:02d}:{minuto:02d}"
    
    
    exibir_agenda(agenda)
    
    print(f"\n⏱️ Total de horas agendadas: {total_horas_agendadas(agenda):.1f}h")
    print(f"🆓 Próximo horário livre: {proximo_horario_livre(agenda)}")
    

    ▶ Saída:

    
    =======================================================
    📅 Agenda do Dia — Los Michelitos
    =======================================================
      🕐 09:00 | Pedro      | Barba                 | 30 min
      🕐 09:30 | Ana        | Corte                 | 45 min
      🕐 10:15 | Carlos     | Corte + Barba         | 60 min
      🕐 11:15 | Hugo       | Hidratação            | 40 min
      🕐 14:00 | Marina     | Sobrancelha           | 20 min
      🕐 14:20 | João       | Corte                 | 45 min
    =======================================================
    
    ⏱️ Total de horas agendadas: 4.0h
    🆓 Próximo horário livre: 15:05
    

    💡 Detalhes importantes do código:

  • Cada agendamento é uma **tupla** — imutável por natureza (um horário não deve ser alterado depois de criado)
  • Usamos **tuple unpacking** no `for` para extrair horário, cliente, serviço e duração
  • O `_` em `for _, _, _, duracao` descarta valores que não vamos usar (convenção Python)
  • Funções pequenas com responsabilidade única facilitam manutenção



  • 🎯 Exercícios Práticos


    1️⃣ Contador de caracteres com dict


    Crie uma função contar_caracteres(texto) que retorna um dicionário com a contagem de cada caractere da string:


    Requisitos:

  • Ignorar espaços em branco
  • Converter para minúsculas
  • Usar `.get()` com valor padrão para contar

  • 
    def contar_caracteres(texto):
        """Retorna um dicionário com a contagem de cada caractere."""
        contagem = {}
        for char in texto.lower():
            if char != " ":
                contagem[char] = contagem.get(char, 0) + 1
        return contagem
    
    frase = "Barbearia Los Michelitos"
    resultado = contar_caracteres(frase)
    
    # Exibindo ordenado
    for char, qtd in sorted(resultado.items()):
        print(f"  {char!r}: {qtd}")
    

    ▶ Saída:

    
      'a': 3
      'b': 2
      'c': 1
      'e': 3
      'h': 1
      'i': 3
      'l': 2
      'm': 1
      'o': 2
      'r': 2
      's': 2
      't': 1
    



    2️⃣ Agenda semanal com tuplas


    Crie uma agenda semanal onde cada dia é uma lista de agendamentos (tuplas). Depois, crie uma função para buscar todos os agendamentos de um cliente pelo nome:


    Requisitos:

  • Cada agendamento é uma tupla: `(horario, servico)`
  • A agenda é um dicionário: dia → lista de tuplas
  • A função `buscar_por_cliente` deve retornar todos os agendamentos

  • 
    # Agenda semanal: dia → [(horario, servico), ...]
    agenda_semanal = {
        "Segunda": [("09:00", "Corte"), ("10:00", "Barba"), ("14:00", "Hidratação")],
        "Terça":   [("09:30", "Corte + Barba"), ("11:00", "Pezinho")],
        "Quarta":  [("10:00", "Barba"), ("14:30", "Corte")],
        "Quinta":  [("08:00", "Corte"), ("09:00", "Barba"), ("10:00", "Sobrancelha")],
        "Sexta":   [("09:00", "Corte + Barba"), ("15:00", "Hidratação")],
        "Sábado":  [("08:00", "Corte"), ("08:30", "Barba"), ("09:00", "Corte")],
    }
    
    
    def total_por_dia(agenda):
        """Retorna um dicionário com o total de agendamentos por dia."""
        return {dia: len(horarios) for dia, horarios in agenda.items()}
    
    
    def total_por_servico(agenda):
        """Retorna a contagem de cada serviço na semana."""
        contagem = {}
        for horarios in agenda.values():
            for _, servico in horarios:
                contagem[servico] = contagem.get(servico, 0) + 1
        return contagem
    
    
    print("📊 Agendamentos por dia:")
    for dia, qtd in total_por_dia(agenda_semanal).items():
        barra = "█" * qtd
        print(f"  {dia:10s} {barra} ({qtd})")
    
    print(f"\n🔝 Serviços mais agendados:")
    for servico, qtd in sorted(total_por_servico(agenda_semanal).items(),
                               key=lambda x: x[1], reverse=True):
        print(f"  ✂️ {servico}: {qtd}x")
    

    ▶ Saída:

    
    📊 Agendamentos por dia:
      Segunda    ███ (3)
      Terça      ██ (2)
      Quarta     ██ (2)
      Quinta     ███ (3)
      Sexta      ██ (2)
      Sábado     ███ (3)
    
    🔝 Serviços mais agendados:
      ✂️ Corte: 6x
      ✂️ Barba: 3x
      ✂️ Corte + Barba: 2x
      ✂️ Hidratação: 2x
      ✂️ Pezinho: 1x
      ✂️ Sobrancelha: 1x
    



    3️⃣ Mesclando cardápios (desafio)


    Crie uma função mesclar_cardapios(cardapio1, cardapio2) que combina dois dicionários de serviços, mantendo o menor preço quando o mesmo serviço aparecer em ambos:


    Requisitos:

  • Se um serviço está nos dois, use o menor preço
  • Retorne o cardápio mesclado
  • Use dict comprehension

  • 
    filial_centro = {
        "Corte": 75,
        "Barba": 40,
        "Hidratação": 60,
        "Sobrancelha": 25,
    }
    
    filial_shopping = {
        "Corte": 70,          # mais barato!
        "Barba": 45,          # mais caro
        "Corte + Barba": 100, # exclusivo do shopping
        "Massagem": 80,       # exclusivo do shopping
    }
    
    
    def mesclar_cardapios(c1, c2):
        """Combina dois cardápios mantendo o menor preço para serviços duplicados."""
        todas_chaves = set(c1) | set(c2)  # União das chaves (sem duplicatas)
        return {
            chave: min(c1.get(chave, float("inf")), c2.get(chave, float("inf")))
            for chave in todas_chaves
        }
    
    
    cardapio_unificado = mesclar_cardapios(filial_centro, filial_shopping)
    
    print("🍽️ Cardápio Unificado (menor preço):")
    for servico, preco in sorted(cardapio_unificado.items()):
        origem = []
        if servico in filial_centro:
            origem.append(f"R$ {filial_centro[servico]:.0f} centro")
        if servico in filial_shopping:
            origem.append(f"R$ {filial_shopping[servico]:.0f} shopping")
        print(f"  {servico:20s} R$ {preco:>6.2f}  ({' vs '.join(origem)})")
    

    ▶ Saída:

    
    🍽️ Cardápio Unificado (menor preço):
      Barba                R$  40.00  (R$ 40 centro vs R$ 45 shopping)
      Corte                R$  70.00  (R$ 75 centro vs R$ 70 shopping)
      Corte + Barba        R$ 100.00  (R$ 100 shopping)
      Hidratação           R$  60.00  (R$ 60 centro)
      Massagem             R$  80.00  (R$ 80 shopping)
      Sobrancelha          R$  25.00  (R$ 25 centro)
    

    💡 Dica AWS: O Amazon DynamoDB é um banco de dados NoSQL chave-valor — exatamente como um dicionário Python em escala de nuvem! Cada item tem uma chave primária (partition key) e atributos (valores). É serverless, escala automaticamente e é usado por aplicações como Netflix, Airbnb e Uber. A API do DynamoDB em Python (boto3) usa dicionários para representar itens. [Doc Amazon DynamoDB](https://docs.aws.amazon.com/dynamodb/)




    📚 Resumo


    ConceitoO que fazDoc Oficial

    |----------|-----------|-------------|

    `dict = {"chave": valor}`Cria um dicionário[doc](https://docs.python.org/3/tutorial/datastructures.html#dictionaries)
    `dict.get(chave, padrão)`Acesso seguro com fallback[doc](https://docs.python.org/3/library/stdtypes.html#dict.get)
    `dict.keys()` / `.values()`Retorna chaves ou valores[doc](https://docs.python.org/3/library/stdtypes.html#dict.keys)
    `dict.items()`Retorna pares (chave, valor)[doc](https://docs.python.org/3/library/stdtypes.html#dict.items)
    `tuple = (1, 2, 3)`Cria uma tupla (imutável)[doc](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences)
    `a, b = b, a`Tuple unpacking / swap[doc](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences)
    `zip(a, b)`Combina iteráveis par a par[doc](https://docs.python.org/3/library/functions.html#zip)
    `enumerate(x, start=1)`Enumera com índice opcional[doc](https://docs.python.org/3/library/functions.html#enumerate)
    `{k: v for k, v in d.items() if cond}`Dict comprehension[doc](https://docs.python.org/3/tutorial/datastructures.html#dictionaries)



    📖 Referências externas


  • [docs.python.org — Dictionaries](https://docs.python.org/3/tutorial/datastructures.html#dictionaries)
  • [docs.python.org — Tuples and Sequences](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences)
  • [docs.python.org — zip()](https://docs.python.org/3/library/functions.html#zip)
  • [docs.python.org — enumerate()](https://docs.python.org/3/library/functions.html#enumerate)
  • [docs.python.org — dict.get()](https://docs.python.org/3/library/stdtypes.html#dict.get)
  • [docs.python.org — dict.items()](https://docs.python.org/3/library/stdtypes.html#dict.items)
  • [Amazon DynamoDB — Banco chave-valor serverless](https://docs.aws.amazon.com/dynamodb/)
  • [boto3 DynamoDB — API Python para DynamoDB](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html)