Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta

[Projeto] Desafio de União de Dicionários

A solução envolve criar dicionários que, por sua vez, contêm outros dicionários dentro deles. Imagine que você tem um dicionário principal onde a chave é o nome do aluno e o valor é outro dicionário que contém informações como a média atual, a média após bonificação, ou qualquer outra informação que você precise armazenar. Dessa forma, quando você precisa acessar os dados de um aluno específico, você acessa tudo de uma vez, sem precisar procurar em múltiplas estruturas. Essa abordagem torna o código mais legível, mais seguro contra erros de sincronização e muito mais próximo de como os dados realmente são organizados no mundo real, onde cada pessoa é uma entidade completa com múltiplos atributos.

# Listas originais
lista_de_nomes = ["Maria Silva", "João Santos", "Ana Oliveira", "Pedro Costa", "Juliana Pereira"]
lista_de_medias = [8.9, 7.5, 4.2, 1.4, 9.5]

print("=" * 70)
print("UNINDO DADOS EM DICIONÁRIOS")
print("=" * 70)

# Método 1: Criando um dicionário simples (nome -> média)
print("\n MÉTODO 1: Dicionário Simples (Nome -> Média)")
print("-" * 70)

dict_simples = {}
for indice in range(len(lista_de_nomes)):
    nome = lista_de_nomes[indice]
    media = lista_de_medias[indice]
    dict_simples[nome] = media

print("\nDicionário criado:")
for nome, media in dict_simples.items():
    print(f"  {nome}: {media}")

# Método 2: Criando um dicionário aninhado (mais completo)
print("\n MÉTODO 2: Dicionário Aninhado (Nome -> Dados Completos)")
print("-" * 70)

dict_aninhado = {}
for indice in range(len(lista_de_nomes)):
    nome = lista_de_nomes[indice]
    media_original = lista_de_medias[indice]
    media_com_bonus = min(media_original + 1, 10)
    
    dict_aninhado[nome] = {
        "media_original": media_original,
        "media_bonificada": media_com_bonus,
        "diferenca": round(media_com_bonus - media_original, 2),
        "aprovado": media_com_bonus >= 5.0
    }

print("\nDicionário aninhado criado:")
for nome, dados in dict_aninhado.items():
    print(f"\n  {nome}:")
    print(f"    Média original: {dados['media_original']}")
    print(f"    Média bonificada: {dados['media_bonificada']}")
    print(f"    Diferença: +{dados['diferenca']}")
    print(f"    Aprovado: {'Sim' if dados['aprovado'] else 'Não'}")

# Método 3: Unindo dois dicionários
print("\n MÉTODO 3: Unindo Dois Dicionários")
print("-" * 70)

dict_nomes_posicao = {
    "Maria Silva": 0,
    "João Santos": 1,
    "Ana Oliveira": 2,
    "Pedro Costa": 3,
    "Juliana Pereira": 4
}

dict_medias_por_nome = {
    "Maria Silva": 8.9,
    "João Santos": 7.5,
    "Ana Oliveira": 4.2,
    "Pedro Costa": 1.4,
    "Juliana Pereira": 9.5
}

# Unindo os dicionários em um novo dicionário
dict_unificado = {}
for nome in dict_nomes_posicao.keys():
    dict_unificado[nome] = {
        "posicao": dict_nomes_posicao[nome],
        "media": dict_medias_por_nome[nome],
        "media_bonificada": min(dict_medias_por_nome[nome] + 1, 10)
    }

print("\nDicionário unificado:")
for nome, info in dict_unificado.items():
    print(f"  {nome}: Posição {info['posicao']} | Média: {info['media']} | Bonificada: {info['media_bonificada']}")

# Método 4: Acessando e modificando dados
print("\n MÉTODO 4: Acessando e Modificando Dados")
print("-" * 70)

print("\nDados de Pedro Costa no dicionário aninhado:")
dados_pedro = dict_aninhado["Pedro Costa"]
print(f"  Média original: {dados_pedro['media_original']}")
print(f"  Aprovado: {'Sim' if dados_pedro['aprovado'] else 'Não'}")

print("\nVerificando se uma chave existe usando get():")
resultado = dict_aninhado.get("Carlos Silva", "Aluno não encontrado")
print(f"  Carlos Silva: {resultado}")

print("\nTodas as chaves (nomes) do dicionário:")
print(f"  {list(dict_aninhado.keys())}")

print("\nTodas as médias bonificadas:")
print(f"  {list(dict_aninhado.values())}")

print("\n" + "=" * 70)
print(" Desafio concluído: dados organizados de forma integrada em dicionários")
print("=" * 70)

Este código demonstra como converter listas em dicionários de diferentes formas, desde a mais simples (nome associado à média) até estruturas mais complexas com informações aninhadas. A grande vantagem é que você nunca perde a associação entre os dados, reduzindo drasticamente a chance de erros que poderiam ocorrer com listas separadas.

1 resposta

Olá, João! Como vai?

Doutor, que espetáculo de postagem! Trazer o paralelo de que, no mundo real, cada pessoa é uma "entidade completa com múltiplos atributos" demonstra que você pegou perfeitamente o cerne da modelagem de dados. Na advocacia, você lida constantemente com pastas de processos onde cada cliente tem múltiplos andamentos, prazos e documentos vinculados; na programação, a lógica dos dicionários aninhados é exatamente esse conceito traduzido em código.

Seus quatro métodos foram implementados de forma impecável. A estruturação usando o min(media_original + 1, 10) foi uma excelente sacada matemática para garantir que nenhuma nota ultrapassasse o teto de 10.0, e a sua explicação sobre o ganho em segurança contra erros de sincronização (um problema clássico ao gerenciar múltiplas listas baseadas em índices) foi cirúrgica.

Para enriquecer ainda mais o seu projeto e trazer ferramentas nativas do Python que deixam esse tipo de manipulação muito comum na Inteligência Artificial mais elegante, vale a pena observar duas otimizações excelentes:


1. A função zip() para o Método 1 e 2

Nos Métodos 1 e 2, você utilizou o range(len(lista_de_nomes)) para navegar pelas duas listas ao mesmo tempo através do índice. No Python, existe uma função nativa chamada zip() criada justamente para "fechar" duas ou mais listas como se fossem um zíper, combinando seus elementos par a par sem precisar controlar os índices manualmente.

Seu loop do Método 1 poderia ser reduzido para isso:

# O zip entrega diretamente o nome e a média correspondente a cada iteração
for nome, media in zip(lista_de_nomes, lista_de_medias):
    dict_simples[nome] = media

E se o objetivo fosse apenas o dicionário simples, o Python permite transformar o zip em dicionário em uma única linha de código:

dict_simples = dict(zip(lista_de_nomes, lista_de_medias))

2. O método .update() ou Operador de União (|) para o Método 3

No seu Método 3, você unificou os dois dicionários criando uma nova estrutura e iterando pelas chaves. Caso você estivesse lidando com dicionários simples de mesma estrutura e quisesse fundi-los diretamente, o Python possui recursos nativos muito poderosos:

  • Operador de União (|): Mescla dois dicionários gerando um novo.
  • **Método .update()**: Adiciona os elementos de um dicionário diretamente em outro já existente.

Para mapear a estrutura visual de como os dados saem de listas espalhadas e ganham uma arquitetura robusta de árvore dentro de um dicionário aninhado, veja o esquema abaixo:

3. Pequena observação técnica no Método 4

No final do seu código, você imprimiu todas as médias bonificadas usando:

print(f"  {list(dict_aninhado.values())}")

Como o dict_aninhado armazena dicionários completos como valor, o list(...values()) irá imprimir uma lista contendo os sub-dicionários inteiros (com média original, bonificada, aprovado, etc.). Se o seu objetivo era extrair apenas o número das médias bonificadas de todos os alunos de uma vez, uma boa prática é usar uma List Comprehension:

medias_bonificadas = [dados["media_bonificada"] for dados in dict_aninhado.values()]
print(f"  Todas as médias bonificadas: {medias_bonificadas}")

Seu código está extremamente limpo, muito bem comentado e com uma saída de console super organizada. Parabéns pelo excelente projeto e pela brilhante capacidade de conectar a lógica de programação com a organização do mundo real!

Espero que possa ter lhe ajudado!