---
title: "Lambda em Python: O que É e Como Funciona | Python Brasil"
url: "https://python.dev.br/glossario/lambda/"
markdown_url: "https://python.dev.br/glossario/lambda.MD"
description: "Aprenda lambda em Python: funções anônimas, uso com map/filter/sorted, closures, boas práticas e quando evitar. Guia completo com exemplos."
date: "2025-06-01"
author: ""
---

# Lambda em Python: O que É e Como Funciona | Python Brasil

Aprenda lambda em Python: funções anônimas, uso com map/filter/sorted, closures, boas práticas e quando evitar. Guia completo com exemplos.


## O que é Lambda?

Uma **lambda** em Python é uma **função anônima** — uma função sem nome — definida em uma única expressão. A palavra-chave `lambda` cria um objeto de função sem precisar do bloco `def`, tornando-a ideal para funções curtas usadas em um único lugar.

A sintaxe completa é:

```python
lambda parametros: expressao
```

A expressao é avaliada e retornada automaticamente — não existe `return` explícito. Lambda suporta todos os tipos de parâmetros que `def` suporta: posicionais, com valor padrão, `*args` e `**kwargs`.

## Exemplos básicos

```python
# Equivalência entre def e lambda
def dobro(x):
    return x * 2

dobro_lambda = lambda x: x * 2

print(dobro(5))         # 10
print(dobro_lambda(5))  # 10

# Múltiplos parâmetros
soma = lambda a, b: a + b
print(soma(3, 7))   # 10

# Parâmetro com valor padrão
potencia = lambda base, exp=2: base ** exp
print(potencia(3))      # 9
print(potencia(2, 10))  # 1024

# Condicional (ternário)
sinal = lambda x: 'positivo' if x > 0 else ('negativo' if x < 0 else 'zero')
print(sinal(-5))   # negativo
print(sinal(0))    # zero
```

## Uso com funções built-in

O principal poder das lambdas aparece quando combinadas com `map()`, `filter()`, `sorted()` e `max()`/`min()`:

```python
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# filter — mantém elementos onde a lambda retorna True
pares = list(filter(lambda x: x % 2 == 0, numeros))
# [2, 4, 6, 8, 10]

# map — transforma cada elemento
cubos = list(map(lambda x: x ** 3, numeros))
# [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

# sorted com key — ordena por critério personalizado
alunos = [('Ana', 8.5), ('Bruno', 7.2), ('Carla', 9.1), ('Diego', 7.2)]
por_nota = sorted(alunos, key=lambda aluno: aluno[1], reverse=True)
# [('Carla', 9.1), ('Ana', 8.5), ('Bruno', 7.2), ('Diego', 7.2)]

# Ordenacao multipla: nota decrescente, nome crescente como desempate
por_nota_nome = sorted(alunos, key=lambda a: (-a[1], a[0]))
# [('Carla', 9.1), ('Ana', 8.5), ('Bruno', 7.2), ('Diego', 7.2)]

# max/min com key
mais_novo = min([{'nome': 'Ana', 'idade': 25}, {'nome': 'Bruno', 'idade': 22}],
                key=lambda p: p['idade'])
print(mais_novo['nome'])   # Bruno
```

## functools.reduce com lambda

```python
from functools import reduce

numeros = [1, 2, 3, 4, 5]

# Soma acumulada
total = reduce(lambda acc, x: acc + x, numeros)
print(total)   # 15

# Produto
produto = reduce(lambda acc, x: acc * x, numeros)
print(produto)   # 120

# Achatar uma lista de listas (flatten)
listas = [[1, 2], [3, 4], [5]]
plana = reduce(lambda acc, x: acc + x, listas)
print(plana)   # [1, 2, 3, 4, 5]

# Encontrar o máximo sem usar max()
maximo = reduce(lambda a, b: a if a > b else b, numeros)
print(maximo)   # 5
```

## Closures com lambda

Lambdas capturam variáveis do escopo ao redor (closure), mas esse comportamento pode gerar surpresas:

```python
# Closure funciona corretamente com parâmetro com valor padrão
def criar_multiplicadores(lista_n):
    return [lambda x, n=n: x * n for n in lista_n]

dobro, triplo, quadruplo = criar_multiplicadores([2, 3, 4])
print(dobro(5))     # 10
print(triplo(5))    # 15
print(quadruplo(5)) # 20

# ARMADILHA CLÁSSICA: captura por referência, não por valor
multiplicadores_errados = [lambda x: x * n for n in [2, 3, 4]]
# Todas as lambdas capturam a mesma variável 'n' — que ao final do loop vale 4
print(multiplicadores_errados[0](5))   # 20 (esperado: 10!)
print(multiplicadores_errados[1](5))   # 20 (esperado: 15!)
print(multiplicadores_errados[2](5))   # 20 (correto por acaso)

# Solucao: use o parametro padrao para capturar o valor no momento da criacao
multiplicadores_corretos = [lambda x, n=n: x * n for n in [2, 3, 4]]
print(multiplicadores_corretos[0](5))  # 10
print(multiplicadores_corretos[1](5))  # 15
```

## Lambda com defaultdict

```python
from collections import defaultdict

# defaultdict aceita um callable sem argumentos como factory
contagem = defaultdict(lambda: 0)
for letra in 'abracadabra':
    contagem[letra] += 1
print(dict(contagem))
# {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}

# Factory mais complexa
inventario = defaultdict(lambda: {'quantidade': 0, 'preco': 0.0})
inventario['maçã']['quantidade'] += 10
inventario['maçã']['preco'] = 2.50
print(inventario['maçã'])    # {'quantidade': 10, 'preco': 2.5}
print(inventario['banana'])  # {'quantidade': 0, 'preco': 0.0}
```

## Lambda vs módulo operator

O módulo `operator` oferece equivalentes funcionais de operadores Python, geralmente mais rápidos que lambdas:

```python
import operator

dados = [{'nome': 'Ana', 'idade': 25}, {'nome': 'Bruno', 'idade': 22}]

# Lambda vs operator.itemgetter
sorted(dados, key=lambda d: d['nome'])          # lambda
sorted(dados, key=operator.itemgetter('nome'))   # operator (mais rápido)

# operator.attrgetter para objetos
from dataclasses import dataclass

@dataclass
class Produto:
    nome: str
    preco: float

produtos = [Produto('Café', 15.0), Produto('Açúcar', 8.5)]
mais_barato = min(produtos, key=operator.attrgetter('preco'))
# equivalente a: key=lambda p: p.preco

# operator.methodcaller
palavras = ['banana', 'MAÇÃ', 'cereja']
ordenadas = sorted(palavras, key=operator.methodcaller('lower'))
# equivalente a: key=lambda s: s.lower()
```

## Lambda em callbacks de GUI (tkinter)

```python
import tkinter as tk

def criar_interface():
    janela = tk.Tk()
    janela.title("Calculadora Simples")

    resultado = tk.StringVar(value="0")
    tk.Label(janela, textvariable=resultado, font=('Arial', 24)).pack()

    # Lambda captura o valor atual de 'n' no momento de criação do botão
    for n in range(10):
        tk.Button(
            janela,
            text=str(n),
            command=lambda v=n: resultado.set(str(v))
        ).pack(side=tk.LEFT)

    # Sem o truque n=n, todas as lambdas apontariam para n=9
    tk.mainloop()
```

## Limitações do lambda

Lambda tem restrições importantes que `def` não tem:

```python
# 1. Apenas UMA expressão — sem múltiplas instruções
# f = lambda x: x = x + 1; return x   # SyntaxError

# 2. Sem docstring
def com_doc(x):
    """Retorna o dobro de x."""
    return x * 2

# lambda x: x * 2  — não tem como adicionar docstring

# 3. Sem anotações de tipo
# f = lambda x: int -> int: x * 2   # SyntaxError

# 4. Sem statements: if sem else, while, for, try/except
# f = lambda x: if x > 0: x else -x   # SyntaxError (sem ternário)
# f = lambda x: x if x > 0 else -x    # OK — isso é uma expressao

# 5. Sem yield (não pode ser generator)
# f = lambda: yield 42   # SyntaxError
```

## Anti-padrões comuns

```python
# EVITE: atribuir lambda a variável — use def
# Ruim (PEP 8 desaprova explicitamente)
quadrado = lambda x: x ** 2

# Bom
def quadrado(x):
    return x ** 2

# EVITE: lambda que chama outra função sem necessidade
# Ruim
resultado = map(lambda x: str(x), numeros)

# Bom — passe a função diretamente
resultado = map(str, numeros)

# EVITE: lambda complexa e ilegível
# Ruim
processar = lambda dados: {k: v for k, v in dados.items() if v is not None and isinstance(v, (int, float))}

# Bom — use def com nome descritivo
def filtrar_numericos(dados):
    """Retorna apenas os pares chave-valor com valores numéricos."""
    return {k: v for k, v in dados.items()
            if v is not None and isinstance(v, (int, float))}
```

## Orientação do PEP 8

O guia de estilo oficial do Python é explícito sobre lambda:

> "Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier."

Em outras palavras: se você precisa dar um nome à função, use `def`. A única exceção razoável são casos onde a lambda é passada diretamente como argumento — especialmente em `key=`, `command=` ou callbacks similares.

## Quando usar lambda: resumo

Use lambda quando:

- A função tem uma única expressão simples.
- É usada apenas uma vez, diretamente como argumento.
- O contexto deixa claro o propósito (ex.: `key=lambda x: x[1]`).

Evite lambda quando:

- A lógica tem mais de uma etapa ou precisa de tratamento de erros.
- A função será reutilizada ou precisa de documentação.
- A expressão for longa o suficiente para dificultar a leitura.

## Termos Relacionados

- [List Comprehension](/glossario/list-comprehension/) — Alternativa mais pythonica a `map`/`filter` com lambda
- [Decorators](/glossario/decorators/) — Funções que modificam outras funções em Python
- [Generators](/glossario/generators/) — Funções que produzem valores sob demanda com `yield`
