Python lambda
Às vezes você precisa de uma função tão pequena que escrever um def inteiro, com nome, dois-pontos, corpo e return, parece exagero. É o caso mais comum de todos: dizer ao sorted por qual critério ordenar uma lista ("pelo preço", "pela nota"). Para isso o Python tem a lambda: uma função escrita numa linha só, no lugar onde ela é usada, e sem nome.
- A escrever uma
lambdae a lê-la como umdefencurtado. - Por que a
lambdasó aceita uma expressão (e nada dereturn,ifde bloco ou atribuição). - O uso principal:
sorted(lista, key=…), para ordenar por preço, por nota, sem ligar para maiúsculas. - O mesmo
key=nomax, nomine no método.sort(). - Quando não usar
lambda, e o que usar no lugar. - Os erros reais:
returndentro dalambda,key=len(), okey=esquecido.
A ideia: o bilhete rápido
A receita do bolo de milho fica no caderno, com título, para ser usada muitas vezes: é o def. Mas quando a Ana pede ao sobrinho "arruma as caixas da mais leve para a mais pesada", ela não abre o caderno para escrever uma receita chamada "como comparar caixas". Ela dá a instrução na hora, de boca, e pronto. A lambda é esse bilhete rápido: uma instrução pequena, escrita no lugar onde é usada, que não precisa de nome porque não vai ser usada em outro lugar.
1. A primeira lambda
As duas funções abaixo fazem a mesma coisa:
def dobro(n):
return n * 2
dobro_lambda = lambda n: n * 2
print(dobro(5))
print(dobro_lambda(5))
$ python3 dobro.py 10 10
- lambda
- A palavra-chave que cria a função. O nome vem da letra grega λ (lambda), usada por matemáticos para escrever funções.
- n
- O parâmetro, como no
def dobro(n). Sem parênteses em volta. - :
- Separa os parâmetros do resultado.
- n * 2
- O resultado. É devolvido automaticamente: não se escreve
return.
Leia lambda n: n * 2 como "uma função que recebe n e devolve n * 2". Repare que a ordem é a mesma do def, só que tudo numa linha:
def | lambda | |
|---|---|---|
| Escrita | def dobro(n): return n * 2 | lambda n: n * 2 |
| Nome | Tem (dobro) | Não tem |
| Corpo | Quantas linhas quiser | Uma expressão só |
return | Escrito | Implícito: o valor da expressão é devolvido |
Ela é uma função de verdade, só que sem nome
No modo interativo (aula O Modo Interativo):
$ python3 Python 3.14.4 (main, Aug 20 2026, 10:41:58) [GCC 15.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> lambda n: n * 2 <function <lambda> at 0x7f3a1ef0b530> >>> (lambda n: n * 2)(5) 10 >>> dobro = lambda n: n * 2 >>> dobro <function <lambda> at 0x7f3a1ef0b530> >>> dobro(7) 14 >>> exit()
- A
lambdasozinha é uma função, mostrada como<function <lambda> at 0x…>(o endereço muda a cada execução, como na aula Funções). - Dá para chamá-la na hora, com parênteses em volta e o argumento depois:
(lambda n: n * 2)(5). Ninguém escreve assim de verdade; é só para ver que funciona. - Mesmo guardada na variável
dobro, ela continua se chamando<lambda>: o nome é da variável, não da função. É por isso que os tracebacks dizemin <lambda>.
Zero, um ou vários parâmetros
somar = lambda a, b: a + b saudacao = lambda: "Bom dia!" situacao = lambda nota: "Aprovada" if nota >= 7 else "Recuperação" print(somar(2, 3)) print(saudacao()) print(situacao(8)) print(situacao(5.5))
$ python3 varios.py 5 Bom dia! Aprovada Recuperação
Vários parâmetros vão separados por vírgula (lambda a, b:); sem parâmetros, nada antes dos dois-pontos (lambda:). A terceira usa o if em uma linha (aula if em uma Linha), que é uma expressão e por isso cabe na lambda. (Estes exemplos guardam a lambda numa variável só para você ver que funciona; a seção 4 explica por que, nos seus programas, isso deve ser um def.)
2. O uso principal: sorted(key=…)
O sorted devolve uma lista nova, ordenada (aula Ordenando Listas). Com o parâmetro key ("chave"), você diz o que comparar em cada item. O key recebe uma função: o sorted a chama uma vez para cada item e ordena pelos resultados.
nomes = ["Bruno", "Ana", "Carla", "Davi"] print(sorted(nomes)) print(sorted(nomes, key=len)) print(sorted(nomes, key=len, reverse=True)) print(nomes)
$ python3 sorted_basico.py ['Ana', 'Bruno', 'Carla', 'Davi'] ['Ana', 'Davi', 'Bruno', 'Carla'] ['Bruno', 'Carla', 'Davi', 'Ana'] ['Bruno', 'Ana', 'Carla', 'Davi']
- Sem
key: ordem alfabética. key=len: osortedcalculalen("Bruno")= 5,len("Ana")= 3,len("Carla")= 5,len("Davi")= 4, e ordena por esses números: 3, 4, 5, 5. Bruno e Carla empataram e ficaram na ordem em que já estavam. Repare:key=len, sem parênteses. Você entrega a função para osortedchamar; não a chama você mesmo.reverse=True: do maior para o menor.- A lista original não mudou: o
sorteddevolve uma nova.
Aqui o len já existia. Quando o critério não existe pronto, é a hora da lambda.
Ordenando os produtos pelo preço
Cada produto é uma tupla (aula Tuplas) com o nome na posição 0 e o preço na posição 1. Para ordenar pelo preço, a chave de cada produto é produto[1]:
produtos = [("Bolo de milho", 18.0), ("Pão francês", 0.8), ("Café", 4.0), ("Sonho", 6.5)]
por_preco = sorted(produtos, key=lambda produto: produto[1])
for nome, preco in por_preco:
print(f"{nome}: R$ {preco:.2f}")
$ python3 produtos.py Pão francês: R$ 0.80 Café: R$ 4.00 Sonho: R$ 6.50 Bolo de milho: R$ 18.00
- key=
- O argumento nomeado (aula Valores Padrão e Argumentos Nomeados) que recebe a função-critério.
- lambda produto: produto[1]
- "Dado um produto, devolva o item 1 dele (o preço)". O
sortedchama essa função para cada tupla: para("Café", 4.0)ela devolve4.0.
Sem o key, o sorted compararia as tuplas inteiras, começando pelo primeiro item, o nome, e a lista sairia em ordem alfabética. A lambda diz: "compare só os preços".
Missão: do jeito que está, o cardápio sai em ordem alfabética. Acrescente ao sorted um key com uma lambda para que ele saia do mais barato para o mais caro.
produtos = [("Bolo de milho", 18.0), ("Pão francês", 0.8), ("Café", 4.0), ("Sonho", 6.5)]
por_preco = sorted(produtos)
for nome, preco in por_preco:
print(f"{nome}: R$ {preco:.2f}")
produtos = [("Bolo de milho", 18.0), ("Pão francês", 0.8), ("Café", 4.0), ("Sonho", 6.5)]
por_preco = sorted(produtos, key=lambda produto: produto[1])
for nome, preco in por_preco:
print(f"{nome}: R$ {preco:.2f}")
Dicionários, e o max com key
Com uma lista de dicionários (aula Dicionários), a chave é o valor de um campo. E o key funciona igual no max e no min:
alunos = [
{"nome": "Ana", "nota": 8.5},
{"nome": "Bruno", "nota": 6.0},
{"nome": "Carla", "nota": 9.5},
]
ranking = sorted(alunos, key=lambda aluno: aluno["nota"], reverse=True)
for aluno in ranking:
print(aluno["nome"], aluno["nota"])
melhor = max(alunos, key=lambda aluno: aluno["nota"])
print("Maior nota:", melhor["nome"])
$ python3 dicionarios.py Carla 9.5 Ana 8.5 Bruno 6.0 Maior nota: Carla
O max com key devolve o item inteiro (o dicionário da Carla), e não só a nota. Por isso dá para pegar o nome dele.
Sem ligar para maiúsculas
Na ordem do Python, as letras maiúsculas (sem acento) vêm todas antes das minúsculas. Uma lista com nomes digitados de qualquer jeito sai estranha:
nomes = ["bruno", "Ana", "carla", "Davi"] print(sorted(nomes)) print(sorted(nomes, key=lambda nome: nome.lower())) print(sorted(nomes, key=str.lower))
$ python3 maiusculas.py ['Ana', 'Davi', 'bruno', 'carla'] ['Ana', 'bruno', 'carla', 'Davi'] ['Ana', 'bruno', 'carla', 'Davi']
A chave nome.lower() (aula Métodos de Texto) compara todos em minúsculas, mas a lista resultante mantém os nomes como eram. A última linha faz o mesmo sem lambda: str.lower já é uma função que recebe um texto e o devolve em minúsculas.
O lower resolve as maiúsculas, mas não os acentos: para o Python, "É" vem depois do "Z".
nomes = ["Érica", "Bruno", "ana", "Zeca"] print(sorted(nomes)) print(sorted(nomes, key=str.lower))
$ python3 acentos.py ['Bruno', 'Zeca', 'ana', 'Érica'] ['ana', 'Bruno', 'Zeca', 'Érica']
Ordenar como no dicionário, com os acentos no lugar certo, pede ferramentas que ficam para mais adiante. Por enquanto, saiba que isso acontece.
O método .sort()
O método .sort() das listas aceita o mesmo key. A diferença é que ele ordena a própria lista, em vez de devolver uma nova:
produtos = [("Bolo de milho", 18.0), ("Pão francês", 0.8), ("Café", 4.0)]
produtos.sort(key=lambda produto: produto[1])
print(produtos)
$ python3 sort_metodo.py
[('Pão francês', 0.8), ('Café', 4.0), ('Bolo de milho', 18.0)]
A lambda também aparece no map e no filter, que têm aula própria: map() e filter().
3. O que cabe numa lambda
O corpo da lambda é uma expressão: algo que produz um valor, como n * 2, produto[1], nome.lower(), "A" if x else "B". Não cabem comandos: return, atribuição (x = …), if com bloco, for, while. Se você precisa de um desses, precisa de um def. Os erros estão em Quando dá errado.
4. Quando não usar lambda
Para dar um nome, use def
Escrever dobro = lambda n: n * 2 funciona, mas o guia de estilo do Python (PEP 8, aula Estilo de Código) pede um def nesse caso. Se a função vai ter nome, o def é mais claro, aceita várias linhas e aparece com o nome certo nos tracebacks (in dobro, e não in <lambda>). A lambda é para quando a função é usada uma vez, ali mesmo, como no key=.
Para regra complicada, use def
A padaria quer ordenar os produtos pelo preço, mas somando R$ 1 de embalagem aos que custam menos de R$ 5. Isso numa lambda ficaria difícil de ler. Com def, cada passo tem a sua linha, e a função tem um nome que explica o critério:
def preco_com_taxa(produto):
nome, preco = produto
if preco < 5:
return preco + 1
return preco
produtos = [("Bolo de milho", 18.0), ("Pão francês", 0.8), ("Café", 4.0)]
print(sorted(produtos, key=preco_com_taxa))
$ python3 grande.py
[('Pão francês', 0.8), ('Café', 4.0), ('Bolo de milho', 18.0)]
Repare: key=preco_com_taxa, sem parênteses, como com o len. O key aceita qualquer função, venha ela de um def, de uma lambda ou do próprio Python.
Formas diferentes de dar o critério ao sorted
def tamanho_do_nome(nome):
return len(nome)
nomes = ["Bruno", "Ana", "Carla"]
print(sorted(nomes, key=tamanho_do_nome))
print(sorted(nomes, key=lambda nome: len(nome)))
print(sorted(nomes, key=len))
$ python3 formas.py ['Ana', 'Bruno', 'Carla'] ['Ana', 'Bruno', 'Carla'] ['Ana', 'Bruno', 'Carla']
| Forma | Quando usar |
|---|---|
Uma função que já existe: key=len, key=str.lower | Sempre que houver uma pronta que faça exatamente o que você quer. É a mais curta. (lambda nome: len(nome) só embrulha o len: não precisa) |
Uma lambda: key=lambda p: p[1] | Critério curto, usado uma vez só: pegar um item da tupla, um campo do dicionário |
Um def: key=preco_com_taxa | Critério com mais de um passo, com if, ou usado em vários lugares |
Quando dá errado
return dentro da lambda
dobro = lambda n: return n * 2
$ python3 lambda_return.py
File "/home/ana/lambda_return.py", line 1
dobro = lambda n: return n * 2
^^^^^^
SyntaxError: invalid syntax
"Sintaxe inválida", com o ^^^^^^ embaixo do return. A lambda já devolve o valor sozinha; o return é um comando, e comandos não cabem nela. Como consertar: lambda n: n * 2.
lambda
guardar = lambda n: total = n
$ python3 lambda_atrib.py
File "/home/ana/lambda_atrib.py", line 1
guardar = lambda n: total = n
^^^^^^^^^^^^^^^
SyntaxError: cannot assign to lambda
"Não dá para atribuir a uma lambda". O Python leu a linha como guardar = (lambda n: total) = n, uma atribuição dupla em que o segundo alvo seria a própria lambda. A mensagem confunde, mas a causa é simples: atribuição não cabe numa lambda. Como consertar: use um def.
key=len(), com parênteses
nomes = ["Bruno", "Ana", "Carla"] print(sorted(nomes, key=len()))
$ python3 key_parenteses.py
Traceback (most recent call last):
File "/home/ana/key_parenteses.py", line 2, in <module>
print(sorted(nomes, key=len()))
~~~^^
TypeError: len() takes exactly one argument (0 given)
"len() recebe exatamente um argumento (foram dados 0)". Com parênteses, o Python chamou o len ali mesmo, sem nada dentro, antes de chegar ao sorted. O key quer a função, não o resultado dela. Como consertar: key=len, sem parênteses.
key=
nomes = ["Bruno", "Ana", "Carla"] print(sorted(nomes, len))
$ python3 sem_key.py
Traceback (most recent call last):
File "/home/ana/sem_key.py", line 2, in <module>
print(sorted(nomes, len))
~~~~~~^^^^^^^^^^^^
TypeError: sorted expected 1 argument, got 2
"sorted esperava 1 argumento, recebeu 2". O key do sorted só pode ser passado com nome (é um parâmetro depois de *, como você viu na aula Valores Padrão e Argumentos Nomeados). Como consertar: sorted(nomes, key=len).
produtos = [("Bolo de milho", 18.0), ("Pão francês", 0.8), ("Café", 4.0)]
por_preco = sorted(produtos, key=lambda produto: produto[2])
$ python3 key_errada.py
Traceback (most recent call last):
File "/home/ana/key_errada.py", line 2, in <module>
por_preco = sorted(produtos, key=lambda produto: produto[2])
File "/home/ana/key_errada.py", line 2, in <lambda>
por_preco = sorted(produtos, key=lambda produto: produto[2])
~~~~~~~^^^
IndexError: tuple index out of range
Dois trechos File na mesma linha 2: o programa principal chamou o sorted, e o sorted chamou a lambda (in <lambda>, já que ela não tem nome). Dentro dela, produto[2] falhou: "índice da tupla fora do intervalo". Cada tupla só tem as posições 0 e 1, e a contagem começa no zero (aula Acessando Itens). Como consertar: o preço é produto[1].
lambda com argumentos de menos
somar = lambda a, b: a + b print(somar(2))
$ python3 lambda_args.py
Traceback (most recent call last):
File "/home/ana/lambda_args.py", line 2, in <module>
print(somar(2))
~~~~~^^^
TypeError: <lambda>() missing 1 required positional argument: 'b'
A mesma mensagem da aula Parâmetros e Argumentos, só que a função aparece como <lambda>(): o nome somar é da variável, e a função não tem nome. Num programa grande, com várias lambda, fica difícil saber de qual delas o erro fala; é mais um motivo para usar def quando a função tem nome.
Referência rápida
| Escrita | O que faz |
|---|---|
lambda x: expressão | Função sem nome que recebe x e devolve a expressão |
lambda a, b: a + b | Dois parâmetros |
lambda: "oi" | Nenhum parâmetro |
sorted(lista, key=lambda item: item[1]) | Lista nova, ordenada pelo item 1 de cada elemento |
sorted(lista, key=…, reverse=True) | Do maior para o menor |
max(lista, key=…) / min(lista, key=…) | O elemento inteiro com a maior / menor chave |
lista.sort(key=…) | Ordena a própria lista |
key=len, key=str.lower | Função pronta: sem lambda e sem parênteses |
| Mensagem | Causa provável |
|---|---|
SyntaxError: invalid syntax no return | return dentro da lambda: tire-o |
SyntaxError: cannot assign to lambda | Atribuição dentro da lambda: use def |
len() takes exactly one argument (0 given) | key=len(): tire os parênteses |
sorted expected 1 argument, got 2 | Faltou o key= |
Erro com in <lambda> no traceback | O problema está dentro da lambda do key |
Exercícios
1. A palavra-chave
Complete para criar uma função que devolve o triplo:
2. Pela idade
Cada pessoa é uma tupla (nome, idade). Complete a posição para ordenar pela idade:
3. Qual destas é igual a def metade(x): return x / 2?
4. Qual chamada ordena os nomes pelo tamanho?
5. Em qual caso é melhor usar def do que lambda?
Missão final: o ranking da turma
Missão: a professora quer a turma em ordem da maior nota para a menor. Troque o ranking = alunos por um sorted com key (uma lambda que pega a nota) e reverse=True.
alunos = [("Ana", 8.5), ("Bruno", 6.0), ("Carla", 9.5), ("Davi", 7.0)]
ranking = alunos
for nome, nota in ranking:
print(f"{nome}: {nota}")
alunos = [("Ana", 8.5), ("Bruno", 6.0), ("Carla", 9.5), ("Davi", 7.0)]
ranking = sorted(alunos, key=lambda aluno: aluno[1], reverse=True)
for nome, nota in ranking:
print(f"{nome}: {nota}")
Resumo
lambda x: expressãoé uma função pequena e sem nome; o valor da expressão é devolvido semreturn.- Só cabe uma expressão: nada de
return, atribuição,forouifcom bloco (oifde uma linha pode). - O uso principal é o
key=dosorted, do.sort(), domaxe domin: a função calcula, para cada item, o que comparar. - O
keyrecebe a função sem parênteses e com o nomekey=. - Se já existe uma função pronta (
len,str.lower), use-a direto. Se o critério tem vários passos, ou se a função vai ter nome, usedef.