Funções de alta ordem recebem outras funções como argumentos.
Elas transformam dados de forma declarativa e elegante.
Primeiramente, map aplica uma função a cada elemento.
Por exemplo, map(lambda x: x*2, [1,2,3]) dobra os valores.
Além disso, filter seleciona elementos que atendem a uma condição.
Assim, você evita loops manuais e código repetitivo.
Consequentemente, o programa fica mais legível e conciso.
Quando utilizar essas funções? Em transformações de coleções.
Também em pipelines de processamento de dados.
Por outro lado, para lógica muito complexa, loops são melhores.
Python suporta essas funções de forma nativa.
Então, vamos explorar cada uma com exemplos práticos.
Três subtítulos guiarão você por essas funções essenciais.
Portanto, ao final, você substituirá loops verbosos por código funcional.
Map: transformando cada elemento
map aplica uma função a todos os itens de um iterável.
O resultado é um iterador com os valores transformados.
Quando usar map? Em conversões e mapeamentos simples.
Por exemplo, converter strings para números ou aplicar fórmulas.
Além disso, map aceita múltiplos iteráveis simultaneamente.
Exemplo de map:
|
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 |
# Map básico numeros = [1, 2, 3, 4, 5] quadrados = list(map(lambda x: x ** 2, numeros)) print("=== Map ===") print(f"Original: {numeros}") print(f"Quadrados: {quadrados}") # Map com função nomeada def dobrar(x): return x * 2 dobrados = list(map(dobrar, numeros)) print(f"Dobrados: {dobrados}") # Map com múltiplos iteráveis lista1 = [1, 2, 3] lista2 = [10, 20, 30] somas = list(map(lambda a, b: a + b, lista1, lista2)) print(f"Somas elemento a elemento: {somas}") # Map com strings nomes = ["ana", "carlos", "beatriz"] maiusculas = list(map(str.upper, nomes)) print(f"Nomes em maiúsculo: {maiusculas}") # Map com tipos diferentes strings = ["1", "2", "3", "4", "5"] inteiros = list(map(int, strings)) print(f"Strings para inteiros: {inteiros}") # Map com dicionários pessoas = [{"nome": "Ana", "idade": 25}, {"nome": "Carlos", "idade": 30}] nomes_idades = list(map(lambda p: f"{p['nome']} tem {p['idade']} anos", pessoas)) print(f"Descrições: {nomes_idades}") # Map lazy (economia de memória) valores = range(1000000) quadrados_lazy = map(lambda x: x ** 2, valores) print(f"Primeiros 5 quadrados lazy: {list(quadrados_lazy)[:5]}") |
Map é ideal para transformações uniformes em sequências. Ele é mais expressivo que loops tradicionais. Portanto, prefira map para operações simples de mapeamento.
Filter: selecionando elementos
filter retorna apenas elementos que satisfazem uma condição.
A função de filtro deve retornar True ou False.
Quando usar filter? Em operações de seleção e limpeza.
Por exemplo, remover valores nulos ou selecionar maiores que um limite.
Assim, você elimina condicionais espalhadas pelo código.
Exemplo de filter:
|
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 |
# Filter básico numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] pares = list(filter(lambda x: x % 2 == 0, numeros)) print("=== Filter ===") print(f"Original: {numeros}") print(f"Números pares: {pares}") # Filter com função nomeada def maior_que_cinco(x): return x > 5 maiores = list(filter(maior_que_cinco, numeros)) print(f"Maiores que 5: {maiores}") # Filter com strings palavras = ["casa", "sol", "python", "programação", "ia"] longas = list(filter(lambda p: len(p) > 4, palavras)) print(f"Palavras com mais de 4 letras: {longas}") # Filter com None (remove valores falsy) dados = [0, 1, False, 2, "", "texto", None, [], 5] truthy = list(filter(None, dados)) print(f"Valores truthy: {truthy}") # Filter com dicionários pessoas = [ {"nome": "Ana", "idade": 17}, {"nome": "Carlos", "idade": 25}, {"nome": "Beatriz", "idade": 16}, {"nome": "Daniel", "idade": 30} ] maiores_de_idade = list(filter(lambda p: p["idade"] >= 18, pessoas)) print(f"Maiores de idade: {maiores_de_idade}") # Combinando map e filter resultado = list( map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numeros)) ) print(f"Quadrados dos números pares: {resultado}") |
Filter é perfeito para limpeza e seleção de dados. Ele torna o código mais legível que condicionais aninhadas. Portanto, use filter para extrair subconjuntos de dados.
Reduce: reduzindo a um único valor
reduce aplica uma função cumulativamente aos elementos.
O resultado é um único valor agregado da sequência.
Quando usar reduce? Em operações de acumulação.
Por exemplo, soma, produto, máximo, mínimo ou concatenação.
Além disso, reduce permite agregadores personalizados complexos.
Exemplo de reduce:
|
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 |
from functools import reduce # Reduce básico (soma) numeros = [1, 2, 3, 4, 5] soma = reduce(lambda a, b: a + b, numeros) print("=== Reduce ===") print(f"Lista: {numeros}") print(f"Soma: {soma}") # Produto produto = reduce(lambda a, b: a * b, numeros) print(f"Produto: {produto}") # Reduce com valor inicial soma_com_inicio = reduce(lambda a, b: a + b, numeros, 100) print(f"Soma com início 100: {soma_com_inicio}") # Maior valor maior = reduce(lambda a, b: a if a > b else b, numeros) print(f"Maior valor: {maior}") # Reduce com strings palavras = ["Python", " ", "é ", "poderoso"] frase = reduce(lambda a, b: a + b, palavras) print(f"Concatenação: {frase}") # Reduce para encontrar o máximo com dicionários pessoas = [ {"nome": "Ana", "idade": 25}, {"nome": "Carlos", "idade": 35}, {"nome": "Beatriz", "idade": 28} ] mais_velho = reduce( lambda a, b: a if a["idade"] > b["idade"] else b, pessoas ) print(f"Pessoa mais velha: {mais_velho}") # Reduce para implementar média def media(lista): soma = reduce(lambda a, b: a + b, lista) return soma / len(lista) print(f"Média dos números: {media(numeros):.2f}") # Reduce com operação personalizada def fatorial(n): return reduce(lambda a, b: a * b, range(1, n + 1)) print(f"Fatorial de 5: {fatorial(5)}") print(f"Fatorial de 7: {fatorial(7)}") # Pipeline completo: map, filter, reduce numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] resultado = reduce( lambda a, b: a + b, map( lambda x: x ** 2, filter(lambda x: x % 2 == 0, numeros) ) ) print(f"\n=== Pipeline Completo ===") print(f"Soma dos quadrados dos pares: {resultado}") print(f"Verificação: 2²+4²+6²+8²+10² = {4+16+36+64+100}") # Comparação com loop tradicional def soma_quadrados_pares_tradicional(numeros): total = 0 for n in numeros: if n % 2 == 0: total += n ** 2 return total tradicional = soma_quadrados_pares_tradicional(numeros) print(f"Versão tradicional: {tradicional}") |
Reduce é poderoso para agregações personalizadas. A fórmula do padrão map-filter-reduce é clara: \(R = \text{reduce}(\text{função}, \text{map}(\text{f}, \text{filter}(\text{pred}, \text{dados})))\) Combine map, filter e reduce para pipelines expressivos. Eles tornam seu código mais declarativo e menos propenso a erros. Map transforma, filter seleciona, reduce agrega. Portanto, use essas funções para processar coleções de forma elegante. Finalmente, pratique com exemplos reais do seu dia a dia.