Comprehensions são uma sintaxe concisa para criar coleções.
Elas existem para listas, dicionários e conjuntos.
Primeiramente, elas substituem loops tradicionais com append.
O resultado é um código mais limpo e legível.
Além disso, comprehensions são geralmente mais rápidas.
Isso acontece porque são otimizadas em C nativo.
Por exemplo, [x*2 for x in range(10)] dobra números.
Sem comprehension, você precisaria de três linhas.
Portanto, o ganho de produtividade é significativo.
Essa característica foi inspirada em Haskell e outras linguagens.
Assim, Python ganhou uma ferramenta expressiva e poderosa.
Sintaxe e características das comprehensions
A sintaxe básica de list comprehension é:
if é opcional e filtra os elementos.
Uma dict comprehension é similar, mas com chave e valor:
if simples.
Isso foi projetado para clareza, não para complexidade.
Portanto, use comprehensions para transformações diretas.
Outra característica importante é a memória eficiente.
Para listas muito grandes, use generator expressions.
Elas usam parênteses em vez de colchetes.
Por exemplo, (x*2 for x in range(10**6)).
Isso não aloca a lista inteira na memória.
Consequentemente, seu programa usa menos RAM.
Essa dica é valiosa para processamento de grandes volumes.
Quando utilizar comprehensions no seu código
Use comprehensions para mapeamentos e filtros simples.
Transformar uma lista aplicando uma função é ideal.
Filtrar elementos baseado em uma condição também funciona bem.
Por exemplo, pares de uma lista: [x for x in lista if x%2==0].
Outro bom uso é criar dicionários a partir de listas.
Também são ótimas para inverter pares chave-valor.
Por outro lado, evite comprehensions com efeitos colaterais.
Imprimir ou salvar arquivos dentro delas confunde.
Primeiramente, mantenha a expressão pura (sem side effects).
Se o loop precisa de múltiplas linhas, use for tradicional.
Além disso, não use para estruturas de dados aninhadas complexas.
Isso foi percebido como anti-padrão pela comunidade.
Portanto, valorize a legibilidade acima da concisão.
Outro bom uso é em testes de transformações de dados.
Você pode rapidamente visualizar resultados no terminal.
Cientistas de dados usam bastante essas construções.
Use também para inicializar dicionários com valores padrão.
Por exemplo, {nome:0 for nome in lista_nomes}.
Isso cria um contador ou acumulador rapidamente.
Portanto, dominar comprehensions é essencial em Python.
Exemplo prático: transformando listas e dicionários
O código abaixo mostra diversos usos de comprehensions. Começamos com listas e evoluímos para dicionários. Adicionamos condições para filtrar dados específicos. Também demonstramos aninhamento (com moderação). Por fim, comparamos performance com loops tradicionais. Observe como o tempo de execução é melhor. Isso ocorre principalmente para grandes volumes. Vamos ao código comentado para explorar cada caso.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
import time # ============================================ # EXEMPLO 1: LIST COMPREHENSION BÁSICA # ============================================ print("=== List Comprehension ===") numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Loop tradicional quadrados_loop = [] for n in numeros: quadrados_loop.append(n ** 2) print(f"Loop: {quadrados_loop}") # List comprehension (muito mais limpo) quadrados_comp = [n ** 2 for n in numeros] print(f"Comprehension: {quadrados_comp}") # Com filtro: apenas pares pares_quadrados = [n ** 2 for n in numeros if n % 2 == 0] print(f"Pares ao quadrado: {pares_quadrados}") # Com transformação dupla texto = ["python", "é", "divertido"] maisculo_comp = [palavra.upper() for palavra in texto] print(f"Caixa alta: {maisculo_comp}") # ============================================ # EXEMPLO 2: DICT COMPREHENSION # ============================================ print("\n=== Dict Comprehension ===") # Criando dicionário a partir de listas frutas = ["maçã", "banana", "laranja", "uva"] precos = [2.50, 1.80, 3.00, 5.50] # Loop tradicional tabela_loop = {} for i in range(len(frutas)): tabela_loop[frutas[i]] = precos[i] print(f"Loop: {tabela_loop}") # Dict comprehension (mais elegante) tabela_comp = {fruta: preco for fruta, preco in zip(frutas, precos)} print(f"Comprehension: {tabela_comp}") # Filtrando produtos caros (acima de R$ 3) caros = {fruta: preco for fruta, preco in tabela_comp.items() if preco > 3} print(f"Produtos caros: {caros}") # Invertendo chave-valor invertido = {preco: fruta for fruta, preco in tabela_comp.items()} print(f"Dicionário invertido: {invertido}") # Criando dicionário com operação quadrados_dict = {n: n**2 for n in range(1, 6)} print(f"Quadrados em dict: {quadrados_dict}") # ============================================ # EXEMPLO 3: SET COMPREHENSION # ============================================ print("\n=== Set Comprehension ===") numeros_repetidos = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4] unicos_quadrados = {n**2 for n in numeros_repetidos} print(f"Únicos elevados ao quadrado: {unicos_quadrados}") # Vogais em uma string frase = "Python é uma linguagem poderosa" vogais = {letra for letra in frase.lower() if letra in 'aeiouáéíóú'} print(f"Vogais encontradas: {vogais}") # ============================================ # EXEMPLO 4: COMPREHENSIONS ANINHADAS (COM CUIDADO) # ============================================ print("\n=== Comprehensions Aninhadas ===") matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # Achatar matriz (lista de listas para uma lista) achatada = [num for linha in matriz for num in linha] print(f"Matriz achatada: {achatada}") # Matriz transposta transposta = [[linha[i] for linha in matriz] for i in range(3)] print(f"Matriz transposta: {transposta}") # ============================================ # EXEMPLO 5: COMPARAÇÃO DE PERFORMANCE # ============================================ print("\n=== Performance: Loop vs Comprehension ===") # Criando uma lista grande tamanho = 10_000_000 # Loop tradicional inicio = time.time() quadrados_loop = [] for i in range(tamanho): quadrados_loop.append(i ** 2) fim = time.time() print(f"Loop tradicional: {fim - inicio:.4f} segundos") # Comprehension inicio = time.time() quadrados_comp = [i ** 2 for i in range(tamanho)] fim = time.time() print(f"List comprehension: {fim - inicio:.4f} segundos") # Generator (economia de memória) inicio = time.time() quadrados_gen = (i ** 2 for i in range(tamanho)) # O generator ainda não foi executado (lazy) fim = time.time() print(f"Generator (criação): {fim - inicio:.6f} segundos") print(f"Primeiro valor do generator: {next(quadrados_gen)}") # ============================================ # EXEMPLO 6: USO EM PROBLEMAS REAIS # ============================================ print("\n=== Problemas Reais com Comprehension ===") # Dados de exemplo: vendas por vendedor vendas = [ ("Ana", 1500), ("Carlos", 2300), ("Ana", 800), ("Beatriz", 3100), ("Carlos", 1200), ("Ana", 500), ] # Total de vendas por vendedor total_por_vendedor = {} for vendedor, valor in vendas: total_por_vendedor[vendedor] = total_por_vendedor.get(vendedor, 0) + valor print(f"Total de vendas: {total_por_vendedor}") # Filtrar vendedores que bateram meta (acima de 2000) meta = 2000 acima_meta = {vendedor: total for vendedor, total in total_por_vendedor.items() if total > meta} print(f"Acima da meta (R$: {meta}): {acima_meta}") # Extrair nomes em maiúsculo (usando list comp) nomes_maiusculo = [nome.upper() for nome in total_por_vendedor.keys()] print(f"Nomes em maiúsculo: {nomes_maiusculo}") |
Nos exemplos, a diferença de sintaxe é clara.
A versão com comprehension reduz drasticamente o código.
Isso acontece sem perder legibilidade ou performance.
Primeiramente, note a ausência de append() manual.
Isso elimina um tipo comum de erro humano.
Além disso, a intenção do código fica evidente.
Qualquer programador Python entende rapidamente.
Por exemplo, [x**2 for x in lista] é autoexplicativo.
Já o loop equivalente exige leitura linha por linha.
Portanto, comprehensions melhoram a comunicação do código.
Use-as sempre que a transformação for clara e direta.
Isso é considerado pythonico pela comunidade.
Outro ponto importante é a performance superior. No teste com 10 milhões de elementos, a diferença aparece. Comprehensions rodam em código C otimizado nativamente. Loops tradicionais têm overhead de interpretação por iteração. Isso foi medido e comprovado em diversos benchmarks. No entanto, a diferença só importa para grandes volumes. Para listas pequenas, a legibilidade é o fator principal. Primeiramente, escreva código claro e correto. Depois, se necessário, otimize onde houver gargalos. Portanto, não transforme todo loop em comprehension cegamente. Avalie o contexto e a complexidade da operação. Assim, você equilibra elegância e manutenibilidade.
Mapeamento 1:1 (ex: quadrados)
Filtros simples (ex: pares)
Transformações de strings
Criação de dicionários
Conjuntos únicos
Inversão de pares
Side effects (print, salvar)
Lógica com muitas linhas
Aninhamento profundo
Tratamento de exceções
Recursão ou iteração complexa
Performance muito crítica
Finalmente, lembre-se das comprehensions para conjuntos.
Use set quando a ordem não importar.
Para dicionários, as chaves devem ser únicas.
Repetições são resolvidas pela última ocorrência.
Além disso, você pode usar condicionais múltiplas.
Por exemplo, [x for x in lista if cond1 and cond2].
Isso é perfeitamente aceitável e legível.
Evite, porém, if-else no final da expressão.
Nesse caso, use expressao if cond else outra.
Isso foi projetado para substituir operadores ternários.
Portanto, explore todas as variantes disponíveis.
A prática leva à maestria nesse recurso versátil.