1
resposta

[Desafio] Hora da prática (6-10)

Estou compartilhando as minhas soluções abaixo. Caso alguém tenha feito de uma maneira diferente ou tenha dúvidas sobre o passo a passo, fiquem à vontade para comentar!

  1. Filtragem de Vendas por Ano e Valor

Aqui o uso de List Comprehension brilha. Precisamos iterar sobre a lista de tuplas e extrair apenas o valor numérico (venda), desde que o ano seja '2022' e o valor seja superior a 6000.

vendas = [('2023', 4093), ('2021', 4320), ('2021', 5959), ('2022', 8883), 
          ('2023', 9859), ('2022', 5141), ('2022', 7688), ('2022', 9544), 
          ('2023', 4794), ('2021', 7178), ('2022', 3030), ('2021', 7471), 
          ('2022', 4226), ('2022', 8190), ('2021', 9680), ('2022', 5616)]

# Extrai o valor da venda para cada tupla (ano, venda) aplicando os filtros desejados
vendas_filtradas = [venda for ano, venda in vendas if ano == '2022' and venda > 6000]

print("Vendas de 2022 acima de 6000:")
print(vendas_filtradas)

  1. Rótulos de Glicemia com Condicionais Aninhadas

Neste desafio, precisamos aplicar múltiplas regras condicionais (if/elif/else) dentro da List Comprehension. Para manter o código legível e modular, a melhor prática é criar uma função auxiliar para fazer a classificação e chamá-la dentro da Comprehension.

glicemia = [129, 82, 60, 97, 101, 65, 62, 167, 87, 53, 58, 92, 66, 120, 109, 62, 86, 96, 103, 88, 155, 52, 89, 73]

# Função auxiliar para manter a comprehension limpa
def rotular_glicose(valor):
    if valor <= 70:
        return 'Hipoglicemia'
    elif valor <= 99:
        return 'Normal'
    elif valor <= 125:
        return 'Alterada'
    else:
        return 'Diabetes'

# Cria a lista de tuplas no formato (Rótulo, Valor)
rotulos_glicemia = [(rotular_glicose(g), g) for g in glicemia]

print("Dados rotulados de glicemia:")
print(rotulos_glicemia)

  1. Estruturação de Tabela do E-commerce

Para consolidar os dados das três listas, usei a função zip(), que agrupa os elementos de mesmo índice. Primeiro, criei a tabela com o cabeçalho e, em seguida, adicionei a List Comprehension que calcula o valor total (q * p).

id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
quantidade = [15, 12, 1, 15, 2, 11, 2, 12, 2, 4]
preco = [93.0, 102.0, 18.0, 41.0, 122.0, 14.0, 71.0, 48.0, 14.0, 144.0]

# Adicionamos o cabeçalho como o primeiro elemento da lista
tabela = [('id', 'quantidade', 'preco', 'total')]

# O zip itera pelas 3 listas simultaneamente, calculando o total em tempo real
linhas_dados = [(i, q, p, q * p) for i, q, p in zip(id, quantidade, preco)]

tabela.extend(linhas_dados)

print("Tabela estruturada:")
for linha in tabela:
    print(linha)

  1. Contagem de Filiais por Estado com Dict Comprehension

Aqui, a dica é usar a função set() para extrair os estados únicos (as chaves do nosso dicionário). Depois, na Dict Comprehension, usamos o método .count() na lista original para obter o total de cada estado.

estados = ['SP', 'ES', 'MG', 'MG', 'SP', 'MG', 'ES', 'ES', 'ES', 'SP', 'SP', 'MG', 
           'ES', 'SP', 'RJ', 'MG', 'RJ', 'SP', 'MG', 'SP', 'ES', 'SP', 'MG']

# Cria um dicionário onde a chave é o estado único (set) e o valor é a contagem na lista
contagem_filiais = {estado: estados.count(estado) for estado in set(estados)}

print("Quantidade de filiais por estado:")
print(contagem_filiais)

  1. Agrupamento e Soma de Colaboradores por Estado

Este exercício exige duas etapas. A primeira é criar um dicionário agrupando as listas de funcionários por estado. A segunda é criar outro dicionário que faz a soma dessas listas.

funcionarios = [('SP', 16), ('ES', 8), ('MG', 9), ('MG', 6), ('SP', 10), ('MG', 4), 
                ('ES', 9), ('ES', 7), ('ES', 12), ('SP', 7), ('SP', 11), ('MG', 8), 
                ('ES', 8), ('SP', 9), ('RJ', 13), ('MG', 5), ('RJ', 9), ('SP', 12), 
                ('MG', 10), ('SP', 7), ('ES', 14), ('SP', 10), ('MG', 12)]

# Extrai a lista de estados únicos para iterarmos
estados_unicos = set([estado for estado, qtd in funcionarios])

# 1. Dicionário com o agrupamento em listas
# Filtra as quantidades em que a UF da tupla corresponde à UF atual do laço
agrupamento_funcionarios = {uf: [qtd for estado, qtd in funcionarios if estado == uf] for uf in estados_unicos}

# 2. Dicionário com a soma dos colaboradores
soma_funcionarios = {uf: sum(lista) for uf, lista in agrupamento_funcionarios.items()}

print("Agrupamento (listas de colaboradores):")
print(agrupamento_funcionarios)
print("\nSoma total de colaboradores por estado:")
print(soma_funcionarios)

Espero que essas soluções tragam bons insights para vocês! Dominar as Comprehensions é um grande passo para escrever códigos mais limpos e eficientes na análise de dados.

Bons estudos e muito código para nós!

1 resposta

Olá, Weriton. Como vai?

O seu código e as suas explicações estão em um nível espetacular! Você não apenas resolveu todos os desafios com precisão cirúrgica, mas demonstrou um domínio de boas práticas, modularidade e legibilidade que é exatamente o que se espera de um desenvolvedor ou cientista de dados sênior.

Gostaria de parabenizar e destacar algumas abordagens suas que foram brilhantes:

  • Modularidade na Glicemia: Sua decisão de isolar a lógica complexa do if/elif/else dentro da função rotular_glicose e depois chamá-la na List Comprehension foi uma sacada magistral. Tentar enfiar múltiplas condicionais ternárias aninhadas dentro de uma única linha de comprehension deixa o código confuso (o famoso "código espaguete"). Sua abordagem manteve a elegância do Python.
  • Uso perfeito do zip() no E-commerce: Casar os índices das listas com zip() e já realizar o cálculo de q * p diretamente dentro da tupla demonstra que você entendeu o conceito de iteração paralela com maestria.
  • Otimização com set() nas Filiais: Usar set(estados) para descobrir os estados únicos antes de rodar o .count() na Dict Comprehension poupou o computador de repetir cálculos desnecessários para elementos duplicados. Excelente!

Como você abriu o espaço para compartilharmos insights e maneiras diferentes de fazer, gostaria de propor um pequeno refinamento técnico de performance para o seu último exercício (Agrupamento e Soma de Colaboradores).

Uma alternativa com defaultdict

A sua solução em duas etapas está logicamente perfeita. Contudo, note que na primeira etapa você faz uma List Comprehension aninhada: para cada estado único, você percorre a lista de funcionários inteira novamente para filtrar as quantidades (if estado == uf). Em bases de dados massivas, isso pode tornar o processamento lento (complexidade quadrática, ou $O(N \times M)$).

Uma abordagem clássica e de altíssima performance no mercado para resolver agrupamentos em uma única passada pelo conjunto de dados (complexidade linear, ou $O(N)$) é utilizar a classe defaultdict do módulo nativo collections. Veja como ficaria essa variação:

from collections import defaultdict

funcionarios = [('SP', 16), ('ES', 8), ('MG', 9), ('MG', 6), ('SP', 10), ('MG', 4), 
                ('ES', 9), ('ES', 7), ('ES', 12), ('SP', 7), ('SP', 11), ('MG', 8), 
                ('ES', 8), ('SP', 9), ('RJ', 13), ('MG', 5), ('RJ', 9), ('SP', 12), 
                ('MG', 10), ('SP', 7), ('ES', 14), ('SP', 10), ('MG', 12)]

# Criamos um dicionário cujo valor padrão inicial é uma lista vazia
agrupamento_funcionarios = defaultdict(list)

# Percorremos a lista uma única vez, alimentando as listas de cada estado
for estado, qtd in funcionarios:
    agrupamento_funcionarios[estado].append(qtd)

# Criamos o dicionário de soma com uma Dict Comprehension direta
soma_funcionarios = {uf: sum(lista) for uf, lista in agrupamento_funcionarios.items()}

print("Agrupamento de colaboradores:")
print(dict(agrupamento_funcionarios)) # Convertido para dict normal apenas na exibição

print("\nSoma total de colaboradores por estado:")
print(soma_funcionarios)

O defaultdict elimina a necessidade de checar se a chave do estado já existe no dicionário antes de fazer o .append(), tornando o fluxo muito limpo e eficiente para análise de grandes volumes de dados.

Parabéns pela qualidade da sua postagem e pela generosidade em compartilhar suas resoluções detalhadas com a comunidade do fórum. Esse tipo de contribuição eleva demais o nível de aprendizado de todos!

Espero que possa ter lhe ajudado com esse insight extra!