Python map() e filter()
Duas tarefas aparecem o tempo todo com listas: transformar cada item (aplicar um desconto em todos os preços, passar todos os nomes para maiúsculas) e filtrar (ficar só com as notas de quem passou). Você já sabe fazer as duas com um for ou com uma list comprehension. O Python tem também duas funções embutidas feitas sob medida para isso: map() e filter(). Nesta aula você vai aprender a usá-las, a ler código de quem usa, e a decidir quando elas são melhores que a comprehension (e quando não são).
map(funcao, lista): aplicar uma função a cada item.filter(funcao, lista): ficar só com os itens em que a função respondeTrue.- Por que o resultado aparece como
<map object at 0x…>e como transformá-lo em lista. - O uso mais comum de todos:
list(map(int, linha.split()))para ler vários números. - A comparar
map/filtercom list comprehension e a escolher. - Os erros reais:
len()com parênteses, a ordem trocada e o'map' object is not subscriptable.
A ideia: a máquina da fábrica e a peneira
Numa fábrica de sucos, as laranjas passam por uma esteira e, uma por uma, entram numa máquina que as transforma em suco. Entram 10 laranjas, saem 10 copos. Isso é o map(): cada item entra numa função e sai transformado. A quantidade não muda.
Na cozinha, a Ana passa o feijão por uma peneira para tirar as pedrinhas. Os grãos bons passam; as pedrinhas ficam. Isso é o filter() ("filtro"): cada item passa por um teste, e só os aprovados continuam. Nenhum item muda, mas a quantidade pode diminuir.
map() | filter() | |
|---|---|---|
| Pergunta para cada item | "Em que você vira?" | "Você passa no teste?" |
| A função devolve | O item novo | True ou False |
| Quantidade de itens | A mesma | A mesma ou menos |
| Os itens | Mudam | Não mudam |
1. map(): transformar cada item
A padaria vai dar 10% de desconto em tudo. O preço com desconto é o preço vezes 0.9:
precos = [10.0, 25.0, 8.0, 40.0]
def com_desconto(preco):
return preco * 0.9
novos = list(map(com_desconto, precos))
print("Antes:", precos)
print("Depois:", novos)
$ python3 desconto.py Antes: [10.0, 25.0, 8.0, 40.0] Depois: [9.0, 22.5, 7.2, 36.0]
- def com_desconto(preco):
- A "máquina": uma função que recebe um preço e devolve o preço com desconto (aula Funções).
- map(com_desconto, precos)
- "Aplique
com_descontoem cada item deprecos." Primeiro a função, depois a lista. Repare:com_descontosem parênteses. Você não está chamando a função; está entregando a função para omap(), que vai chamá-la uma vez para cada preço. - list(…)
- Junta os resultados numa lista nova. (A próxima seção explica por que isso é preciso.)
- Antes: […]
- A lista original não mudou. O
map()cria valores novos.
Por que o list()?
Veja o que o map() devolve sozinho, no 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. >>> nomes = ["ana", "bruno", "clara"] >>> map(str.upper, nomes) <map object at 0x7efeec788400> >>> list(map(str.upper, nomes)) ['ANA', 'BRUNO', 'CLARA']
<map object at 0x7efeec788400> quer dizer "um objeto map, no endereço tal da memória" (esse número muda a cada vez). O map() é preguiçoso, no bom sentido: ele ainda não calculou nada. Só calcula cada item quando alguém pede, por exemplo um for ou o list(). Por isso, para ver ou guardar os resultados, use list(map(…)); para só percorrer, pode usar direto no for:
for nome in map(str.upper, nomes):
print(nome)
Funções prontas também servem
Qualquer função que recebe um valor e devolve outro pode ir no map(): as embutidas (aula Funções Embutidas), os métodos de texto (aula Métodos de Texto) e as lambda (aula lambda):
>>> list(map(len, nomes)) [3, 5, 5] >>> list(map(lambda nome: nome.title(), nomes)) ['Ana', 'Bruno', 'Clara'] >>> list(map(round, [2.7, 3.2, 9.9])) [3, 3, 10]
- map(len, nomes)
- O tamanho de cada nome.
- map(str.upper, nomes)
str.upperé o método.upper()dos textos, escrito como função:str.upper("ana")é o mesmo que"ana".upper().- map(lambda nome: nome.title(), nomes)
- Uma
lambdaé uma função de uma linha, sem nome, escrita ali mesmo. Muito comum commap(). - map(round, […])
- Arredonda cada número.
O uso mais comum: vários números numa linha
O input() sempre devolve texto (aula input()). Quando a pessoa digita vários números numa linha só, o .split() separa os pedaços, e o map(int, …) converte cada pedaço em número:
linha = input("Digite as idades, separadas por espaço: ")
idades = list(map(int, linha.split()))
print("Idades:", idades)
print("Soma:", sum(idades))
$ python3 numeros_input.py Digite as idades, separadas por espaço: 12 35 7 Idades: [12, 35, 7] Soma: 54
- linha.split()
- Corta o texto
"12 35 7"nos espaços:['12', '35', '7'], uma lista de textos. - map(int, …)
- Aplica
int()em cada pedaço:'12'vira12(aula Conversão de Tipos). - list(…)
- Guarda tudo numa lista, para usar no
printe nosum.
Missão: as idades chegaram como texto, e o sum() dá erro (rode para ver). Use map(int, …) para converter todas e mostrar Soma: 54.
idades_texto = ["12", "35", "7"]
idades = idades_texto
print("Soma:", sum(idades))
idades_texto = ["12", "35", "7"]
idades = list(map(int, idades_texto))
print("Soma:", sum(idades))
Se a função recebe dois valores, passe duas listas: o map() pega um item de cada, como o zip() (aula enumerate() e zip()).
>>> list(map(lambda p, q: p * q, [25.9, 18.5], [2, 1])) [51.8, 18.5]
Preço vezes quantidade: 25.9 × 2 e 18.5 × 1.
2. filter(): ficar só com alguns itens
A professora quer só as notas de quem passou, 7 ou mais. A "peneira" é uma função que responde True (passa) ou False (fica):
notas = [9.0, 6.5, 8.0, 5.0, 7.0]
def passou(nota):
return nota >= 7
aprovadas = list(filter(passou, notas))
print("Todas:", notas)
print("Aprovadas:", aprovadas)
$ python3 aprovados.py Todas: [9.0, 6.5, 8.0, 5.0, 7.0] Aprovadas: [9.0, 8.0, 7.0]
- def passou(nota):
- A peneira: recebe uma nota e devolve
Truese ela for 7 ou mais (aula Comparações). - filter(passou, notas)
- "Fique só com as notas em que
passourespondeTrue." De novo: primeiro a função (sem parênteses), depois a lista. - [9.0, 8.0, 7.0]
- As notas que passaram, na mesma ordem em que estavam. O 6.5 e o 5.0 ficaram na peneira. O 7.0 passou, porque o teste é
>=.
Como o map(), o filter() devolve um objeto preguiçoso (<filter object at 0x…>), por isso o list(). Com lambda, cabe numa linha:
>>> notas = [9.0, 6.5, 8.0, 5.0, 7.0] >>> list(filter(lambda nota: nota >= 7, notas)) [9.0, 8.0, 7.0]
filter(None, …): tirar os vazios
Uma pesquisa teve respostas em branco. Com None no lugar da função, o filter() fica com os itens que valem True numa condição, e textos vazios valem False (aula Booleanos):
>>> respostas = ["sim", "", "não", "", "talvez"] >>> list(filter(None, respostas)) ['sim', 'não', 'talvez']
Missão: a Ana quer só os produtos que custam menos de 10 reais. Use filter() para mostrar [8.0, 4.25, 9.9].
precos = [12.5, 8.0, 4.25, 30.0, 9.9] baratos = precos print(baratos)
precos = [12.5, 8.0, 4.25, 30.0, 9.9] baratos = list(filter(lambda preco: preco < 10, precos)) print(baratos)
3. map e filter × list comprehension
Tudo o que map() e filter() fazem, a list comprehension também faz. Compare, lado a lado, com os mesmos dados:
>>> precos = [10.0, 25.0, 8.0, 40.0] >>> list(map(lambda preco: preco * 0.9, precos)) [9.0, 22.5, 7.2, 36.0] >>> [preco * 0.9 for preco in precos] [9.0, 22.5, 7.2, 36.0] >>> list(filter(lambda nota: nota >= 7, notas)) [9.0, 8.0, 7.0] >>> [nota for nota in notas if nota >= 7] [9.0, 8.0, 7.0] >>> [r for r in respostas if r] ['sim', 'não', 'talvez']
Os resultados são iguais. E quando você precisa filtrar e transformar ao mesmo tempo (as notas de quem passou, multiplicadas por 10)? Veja a diferença na leitura:
>>> list(map(lambda nota: nota * 10, filter(lambda nota: nota >= 7, notas))) [90.0, 80.0, 70.0] >>> [nota * 10 for nota in notas if nota >= 7] [90.0, 80.0, 70.0]
Com map e filter, você lê de dentro para fora, e há duas lambda. A comprehension se lê da esquerda para a direita, quase como uma frase: "nota vezes 10, para cada nota em notas, se a nota for 7 ou mais".
| Situação | Prefira | Por quê |
|---|---|---|
Aplicar uma função que já existe (int, str, len, round, uma def sua) | map(int, partes) | Curto e claro, sem lambda |
Uma conta ou expressão (preco * 0.9) | [preco * 0.9 for preco in precos] | Sem lambda, se lê como uma frase |
Filtrar com uma condição (nota >= 7) | [nota for nota in notas if nota >= 7] | Idem |
| Filtrar e transformar juntos | Comprehension | Um map(filter(…)) com duas lambda fica difícil de ler |
| Só percorrer, sem guardar a lista | for nome in map(str.upper, nomes): | O map calcula um de cada vez e não monta uma lista na memória |
| Regra complicada, com vários passos | Um for comum | Cabe if/else, print e comentários |
A maioria dos programadores Python prefere a list comprehension e reserva o map() para os casos com uma função pronta, como o map(int, …). Mesmo assim, vale conhecer bem os dois: você vai encontrar map e filter em muito código, e em outras linguagens (JavaScript, por exemplo) eles são o jeito principal.
Quando dá errado
O erro mais comum: escrever a função com () dentro do map().
(A lista é a mesma de antes: nomes = ["ana", "bruno", "clara"].)
>>> list(map(len(), nomes))
Traceback (most recent call last):
File "<python-input-18>", line 1, in <module>
list(map(len(), nomes))
~~~^^
TypeError: len() takes exactly one argument (0 given)
>>> list(map(str.upper(), nomes))
Traceback (most recent call last):
File "<python-input-23>", line 1, in <module>
list(map(str.upper(), nomes))
~~~~~~~~~^^
TypeError: unbound method str.upper() needs an argument
- ~~~^^ embaixo de len()
- As marcas apontam para
len(), e não para omap: o erro acontece antes de omap()começar. - TypeError: len() takes exactly one argument (0 given)
- "
len()recebe exatamente um argumento (0 dados)." Com os parênteses, o Python tentou chamar olenali mesmo, sem nada dentro. - TypeError: unbound method str.upper() needs an argument
- O mesmo problema com o método: "o método
str.upper(), solto, precisa de um argumento" (o texto a ser convertido).
Como consertar: passe a função sem parênteses: map(len, nomes), map(str.upper, nomes). Quem chama é o map().
>>> list(map(nomes, len))
Traceback (most recent call last):
File "<python-input-19>", line 1, in <module>
list(map(nomes, len))
~~~^^^^^^^^^^^^
TypeError: 'builtin_function_or_method' object is not iterable
"Um objeto builtin_function_or_method (uma função embutida) não é iterável", ou seja, não dá para percorrer. O map() esperava a lista em segundo lugar, recebeu a função len e tentou percorrê-la como se fosse uma lista. Como consertar: a ordem é sempre função primeiro, lista depois: map(len, nomes), filter(passou, notas).
map como se fosse uma lista
nomes = ["ana", "bruno", "clara"] maiusculos = map(str.upper, nomes) print(maiusculos[0])
$ python3 map_objeto.py
Traceback (most recent call last):
File "/home/ana/map_objeto.py", line 3, in <module>
print(maiusculos[0])
~~~~~~~~~~^^^
TypeError: 'map' object is not subscriptable
"Um objeto map não aceita índice" (subscript é o [0]). O map não é uma lista: ele entrega os itens um de cada vez e não guarda nenhum. Pela mesma razão, ele só pode ser percorrido uma vez; na segunda, vem vazio, sem erro:
>>> dobrados = map(lambda n: n * 2, [1, 2, 3]) >>> list(dobrados) [2, 4, 6] >>> list(dobrados) []
Como consertar: se você vai usar o resultado mais de uma vez, ou pelo índice, transforme em lista logo de cara: maiusculos = list(map(str.upper, nomes)). (O mesmo vale para o filter. A aula Iteradores explica esse comportamento.)
Referência rápida
| Escrita | O que faz | Comprehension equivalente |
|---|---|---|
list(map(f, lista)) | Aplica f em cada item | [f(x) for x in lista] |
list(map(int, linha.split())) | Converte cada pedaço do texto em número | [int(p) for p in linha.split()] |
list(map(f, a, b)) | f com um item de cada lista | [f(x, y) for x, y in zip(a, b)] |
list(filter(f, lista)) | Fica com os itens em que f dá True | [x for x in lista if f(x)] |
list(filter(None, lista)) | Tira os itens "vazios" ("", 0, None…) | [x for x in lista if x] |
for x in map(f, lista): | Percorre os resultados sem montar uma lista | — |
| Sintoma | Causa provável |
|---|---|
<map object at 0x…> ou <filter object at 0x…> | Faltou o list(…) para ver os resultados |
TypeError: len() takes exactly one argument (0 given) | Função com parênteses dentro do map(): tire os () |
TypeError: … object is not iterable | Ordem trocada: a função vem primeiro, a lista depois |
TypeError: 'map' object is not subscriptable | Índice num map: use list(map(…)) |
A segunda volta num map guardado vem vazia | O map (e o filter) só pode ser percorrido uma vez |
Exercícios
1. Transformar
Complete para converter os textos em números inteiros:
2. Filtrar
Complete para ficar só com as notas maiores que 8:
3. A comprehension equivalente
Complete a list comprehension que faz o mesmo que list(filter(lambda n: n > 8, notas)):
4. A lista precos tem 5 itens. Quantos itens tem list(map(round, precos))?
5. Qual está escrito do jeito certo?
6. O que print(map(str.upper, ["a", "b"])) mostra?
Missão final: de map/filter para comprehension
Missão: o código abaixo funciona, mas é difícil de ler. Reescreva a linha do resultado como uma list comprehension (com for e if dentro dos colchetes), sem mudar a saída.
notas = [9.0, 6.5, 8.0, 5.0, 7.0] resultado = list(map(lambda nota: nota * 10, filter(lambda nota: nota >= 7, notas))) print(resultado)
notas = [9.0, 6.5, 8.0, 5.0, 7.0] resultado = [nota * 10 for nota in notas if nota >= 7] print(resultado)
Resumo
map(funcao, lista)aplica a função em cada item: mesma quantidade, itens transformados.filter(funcao, lista)fica só com os itens em que a função respondeTrue: itens iguais, quantidade igual ou menor.- A função vai sem parênteses e antes da lista:
map(len, nomes). - Os dois devolvem objetos preguiçosos (
<map object …>): uselist(…)para ver, guardar, usar índice ou percorrer mais de uma vez. list(map(int, linha.split()))é o jeito clássico de ler vários números numa linha.- Com uma conta ou condição, a list comprehension costuma ser mais clara; com uma função pronta, o
map()brilha.