Guia Definitivo da Função Map do Python para Processamento de Dados

Introdução

Podemos usar a função interna do Python map() para aplicar uma função a cada item em um iterável (como uma lista ou dicionário) e retornar um novo iterador para recuperar os resultados. map() retorna um objeto de mapeamento (um iterador), que podemos usar em outras partes do nosso programa. Também podemos passar o objeto de mapeamento para a função list(), ou outro tipo de sequência, para criar um iterável.

A sintaxe da função map() é a seguinte:

map(function, iterable, [iterable 2, iterable 3, ...])

Em vez de usar um laço for, a função map() fornece uma maneira de aplicar uma função a cada item em um iterável. Portanto, muitas vezes pode ser mais eficiente, pois aplica a função apenas a um item de cada vez, em vez de fazer cópias dos itens em outro iterável. Isso é particularmente útil ao trabalhar em programas que processam grandes conjuntos de dados. map() também pode receber vários iteráveis como argumentos para a função, enviando um item de cada iterável para a função de cada vez.

Neste tutorial, vamos revisar três maneiras diferentes de trabalhar com map(): com uma função lambda, com uma função definida pelo usuário e, finalmente, com uma função embutida usando múltiplos argumentos iteráveis.

Usando uma Função Lambda

O primeiro argumento para map() é uma função, que usamos para aplicar a cada item. O Python chama a função uma vez para cada item no iterável que passamos para map() e retorna o item manipulado dentro de um objeto map. Para o primeiro argumento da função, podemos passar uma função definida pelo usuário ou podemos usar funções lambda, particularmente quando a expressão é menos complexa.

A sintaxe de map() com uma função lambda é a seguinte:

map(lambda item: item[] expression, iterable)

Com uma lista como a seguinte, podemos implementar uma função lambda com uma expressão que queremos aplicar a cada item na nossa lista:

numbers = [10, 15, 21, 33, 42, 55]

Para aplicar uma expressão a cada um dos nossos números, podemos usar map() e lambda:

mapped_numbers = list(map(lambda x: x * 2 + 3, numbers))

Aqui declaramos um item na nossa lista como x. Em seguida, adicionamos nossa expressão. Passamos nossa lista de números como o iterável para map().

Para receber os resultados disso imediatamente, imprimimos uma lista do objeto map:

print(mapped_numbers)
Output
[23, 33, 45, 69, 87, 113]

Usamos list() para que o objeto map seja retornado como uma lista, em vez de um objeto menos legível como: <map object at 0x7fc250003a58>. O objeto map é um iterador sobre nossos resultados, então poderíamos percorrê-lo com for ou podemos usar list() para transformá-lo em uma lista. Estamos fazendo isso aqui porque é uma boa maneira de revisar os resultados.

No final, map() é mais útil ao trabalhar com grandes conjuntos de dados, então provavelmente trabalharíamos mais com o objeto map e, geralmente, não estaríamos usando um construtor como list() neles.

Para conjuntos de dados menores, compreensões de listas podem ser mais adequadas, mas para os propósitos deste tutorial estamos usando um pequeno conjunto de dados para demonstrar map().

Implementando uma Função Definida pelo Usuário

De forma semelhante a uma lambda, podemos usar uma função que definimos para aplicar a um iterável. Enquanto as funções lambda são mais úteis para implementar quando você está trabalhando com uma expressão de uma linha, funções definidas pelo usuário são mais apropriadas quando a expressão cresce em complexidade. Além disso, quando precisamos passar outro pedaço de dados para a função que você está aplicando ao seu iterável, funções definidas pelo usuário podem ser uma escolha melhor para legibilidade.

Por exemplo, no iterável a seguir, cada item é um dicionário que contém diferentes detalhes sobre cada uma de nossas criaturas do aquário:

aquarium_creatures = [
 {"name": "sammy", "species": "shark", "tank number": 11, "type": "fish"},
 {"name": "ashley", "species": "crab", "tank number": 25, "type": "shellfish"},
 {"name": "jo", "species": "guppy", "tank number": 18, "type": "fish"},
 {"name": "jackie", "species": "lobster", "tank number": 21, "type": "shellfish"},
 {"name": "charlie", "species": "clownfish", "tank number": 12, "type": "fish"},
 {"name": "olly", "species": "green turtle", "tank number": 34, "type": "turtle"}
]

Decidimos que todas as criaturas do aquário, na verdade, vão se mudar para o mesmo tanque. Precisamos atualizar nossos registros para refletir que todas as nossas criaturas estão se mudando para o tanque 42. Para que map() acesse cada dicionário e cada par chave:valor nos dicionários, construímos uma função aninhada:

def assign_to_tank(aquarium_creatures, new_tank_number):
 def apply(x):
  x["tank number"] = new_tank_number
  return x
 return map(apply, aquarium_creatures)

Definimos uma função assign_to_tank() que recebe aquarium_creatures e new_tank_number como parâmetros. Em assign_to_tank() passamos apply() como a função para map() na linha final. A função assign_to_tank retornará o iterador resultante de map().

apply() recebe x como argumento, que representa um item da nossa lista — um único dicionário.

Em seguida, definimos que x é a chave "tank number" de aquarium_creatures e que deve armazenar o new_tank_number passado. Retornamos cada item após aplicar o novo número do tanque.

Chamamos assign_to_tank() com nossa lista de dicionários e o novo número do tanque que queremos substituir para cada criatura:

assigned_tanks = assign_to_tank(aquarium_creatures, 42)

Uma vez que a função é concluída, temos nosso objeto de mapeamento armazenado na variável assigned_tanks, que transformamos em uma lista e imprimimos:

print(list(assigned_tanks))

Receberemos a seguinte saída deste programa:

Output
[{'name': 'sammy', 'species': 'shark', 'tank number': 42, 'type': 'fish'}, {'name': 'ashley', 'species': 'crab', 'tank number': 42, 'type': 'shellfish'}, {'name': 'jo', 'species': 'guppy', 'tank number': 42, 'type': 'fish'}, {'name': 'jackie', 'species': 'lobster', 'tank number': 42, 'type': 'shellfish'}, {'name': 'charlie', 'species': 'clownfish', 'tank number': 42, 'type': 'fish'}, {'name': 'olly', 'species': 'green turtle', 'tank number': 42, 'type': 'turtle'}]

Mapeamos o novo número do tanque para nossa lista de dicionários. Usando uma função que definimos, podemos incorporar map() para aplicar a função de forma eficiente em cada item da lista.

Usando uma Função Interna com Múltiplos Iteráveis

Da mesma forma que as funções lambda ou nossas próprias funções definidas, podemos usar funções internas do Python com map(). Para aplicar uma função com múltiplos iteráveis, passamos o nome de outro iterável seguindo o primeiro. Por exemplo, usando a pow() função que recebe dois números para encontrar a potência do número base para o expoente fornecido.

Aqui temos nossas listas de inteiros que gostaríamos de usar com pow():

base_numbers = [2, 4, 6, 8, 10]
powers = [1, 2, 3, 4, 5]

Em seguida, passamos pow() como nossa função para map() e fornecemos as duas listas como nossos iteráveis:

numbers_powers = list(map(pow, base_numbers, powers))

print(numbers_powers)

map() aplicará a função pow() ao mesmo item em cada lista para fornecer a potência. Portanto, nossos resultados mostrarão 2**1, 4**2, 6**3, e assim por diante:

Output
[2, 16, 216, 4096, 100000]

Se fornecermos map() com um iterável que seja mais longo do que o outro, map() parará de calcular assim que atingir o final do iterável mais curto. No programa a seguir, estamos estendendo base_numbers com três números adicionais:

base_numbers = [2, 4, 6, 8, 10, 12, 14, 16]
powers = [1, 2, 3, 4, 5]

numbers_powers = list(map(pow, base_numbers, powers))

print(numbers_powers)

Como resultado, nada mudará dentro do cálculo deste programa e, portanto, ainda produzirá o mesmo resultado:

Output
[2, 16, 216, 4096, 100000]

Usamos a função map() com uma função embutida do Python e vimos que ela pode lidar com múltiplos iteráveis. Também revisamos que map() continuará a processar múltiplos iteráveis até alcançar o final do iterável com o menor número de itens.

Conclusão

Neste tutorial, exploramos vários métodos de utilização da função map() em Python. Agora você tem a capacidade de usar map() com funções personalizadas, expressões lambda e outras funções embutidas. Além disso, map() pode ser aplicado a funções que exigem múltiplos iteráveis, aumentando sua versatilidade em tarefas de processamento de dados.

Para fins de demonstração, convertemos os resultados de map() diretamente em uma lista. Em aplicações práticas, o objeto map retornado pode ser manipulado ainda mais para atender a necessidades específicas.

Para aprofundar sua compreensão de Python, por favor, utilize os seguintes recursos:

Esses recursos fornecerão a você uma compreensão abrangente das capacidades do Python e como utilizá-las efetivamente em seus projetos.

Se você gostaria de aprender mais sobre Python, confira nossa série Como Programar em Python e nossa página de tópicos sobre Python. Para aprender mais sobre como trabalhar com conjuntos de dados em programação funcional, confira nosso artigo sobre a filter() função.

Perguntas Frequentes

O que faz a função map() em Python?

A função map() em Python recebe uma função e um ou mais iteráveis e retorna um iterador que aplica a função dada a cada elemento dos iteráveis fornecidos. Em outras palavras, ela “mapeia” a função em cada item do iterável. Por exemplo:

numbers = [1, 2, 3, 4]
squares = map(lambda x: x**2, numbers)

Aqui, squares será um iterador de 1, 4, 9, 16.

Como você cria um mapa em Python?

Você cria um objeto de mapa chamando a função embutida map() com uma função e pelo menos um iterável como argumentos. Por exemplo:

def add_one(x):
    return x + 1

my_list = [1, 2, 3]
mapped = map(add_one, my_list)  # Cria um objeto de mapa

Você pode então iterar sobre o mapeado ou convertê-lo em uma lista para ver os resultados:

print(list(mapped))  # [2, 3, 4]

O mapa é preguiçoso em Python?

Sim, no Python 3, map() retorna um iterador preguiçoso, o que significa que ele não processa ou armazena todos os resultados na memória de uma vez. Em vez disso, ele calcula cada resultado sob demanda à medida que você itera sobre ele. Isso pode ser mais eficiente em termos de memória, especialmente para grandes conjuntos de dados, mas também significa que você não pode indexar diretamente ou iterar repetidamente sobre o mesmo objeto de mapa sem reconstruí-lo.

Como funciona a função map()?

A função map() funciona da seguinte maneira:

  1. Você fornece uma função e um ou mais iteráveis.
  2. map() recupera um elemento de cada iterável.
  3. Ela chama a função com esses elementos como argumentos.
  4. Ela gera o resultado dessa chamada de função.
  5. Repete esse processo até que qualquer um dos iteráveis seja esgotado.

Se vários iteráveis forem fornecidos, map() para quando o iterável mais curto é esgotado. Por exemplo:

numbers = [1, 2, 3]
others = [10, 20, 30]
result = map(lambda x, y: x + y, numbers, others)
print(list(result))  # [11, 22, 33]

Devo usar map em Python?

Se você deve usar map() depende da preferência pessoal e da legibilidade:

Prós:

  • Pode ser mais conciso em alguns casos.
  • Pode ser ligeiramente mais rápido do que compreensões de lista em certos cenários (embora muitas vezes não de forma significativa).

Contras:

  • Código usando compreensões de lista ou expressões geradoras é frequentemente considerado mais “pythônico” e mais facilmente legível.
  • Programadores Python mais novos podem achar as list comprehensions mais intuitivas.

Em resumo, use map() se isso tornar seu código mais claro e direto. Caso contrário, list comprehensions ou expressões geradoras são uma alternativa muito comum.

Como converter map em string no Python?

Um objeto map é um iterador, não uma string. Se você quiser converter os resultados de uma chamada map() em uma string, primeiro precisa iterar sobre ele. Abordagens comuns incluem:

  • Converter para uma lista e depois para uma representação em string:
mapped = map(str, [1, 2, 3])
string_representation = str(list(mapped))  # "[‘1’, ‘2’, ‘3’]"
  • Unir os resultados se eles forem elementos de string:
mapped = map(str, [1, 2, 3])
joined_string = ''.join(mapped)  # "123"

O melhor método depende de se você deseja uma representação de lista legível por humanos (str(list(...))) ou uma concatenação dos resultados (''.join(...)).

O que faz map count()?

map objetos em Python não possuem um método count() embutido. O método count() está disponível em listas, strings e certas outras coleções. Se você quiser contar as ocorrências de um valor produzido por um objeto map, primeiro deve convertê-lo em uma lista (o que consome o iterador):

mapped = map(lambda x: x*2, [1, 2, 3, 2])
mapped_list = list(mapped)
count_of_4 = mapped_list.count(4)  # 2, porque 2*2=4 aparece duas vezes

Se você precisar de uma contagem sem converter para uma lista, você pode iterar manualmente:

count_of_value = sum(1 for x in map(lambda x: x*2, [1, 2, 3, 2]) if x == 4)

O que map e filter fazem em Python?

  • map(function, iterable): Aplica a função a cada elemento do iterável e retorna um iterador dos resultados.

  • filter(function, iterable): Retorna um iterador de elementos do iterável para os quais function(element) é Verdadeiro. Se a função for None, retorna elementos que são verdadeiros por si mesmos.

Por exemplo:

nums = [1, 2, 3, 4, 5]
mapped_nums = map(lambda x: x*2, nums)        # [2, 4, 6, 8, 10]
filtered_nums = filter(lambda x: x > 2, nums) # [3, 4, 5]

map transforma cada elemento, enquanto filter seleciona certos elementos com base em uma condição.

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-the-python-map-function