– Functions usadas como parâmetro e Expressões Lambda – Functions em Iterables
e a função map
e a função map
Veremos agora alguns casos que nos permitem usar funções dentro de funções. Na prática eles farão o papel do List Comprehension. Novamente, não são linhas de código obrigatórias, pois existem formas de escrever o código da mesma forma sem o uso destas funções.
A primeira função que veremos é o MAP. Ela nos permite aplicar uma função a cada um dos itens de um iterable. Lembrando que os iterables são listas, dicionários, strings etc.
Abaixo definimos o formato padrão de uma expressão MAP:
lista = list(map(função, iterable_original))
Voltando para nosso exercício de padronização de códigos, vamos entender como poderíamos usar a função MAP para responder este caso. Perceba que primeiro definimos uma função que padroniza os códigos.
Usamos a função definida DENTRO do argumento do MAP juntamente da lista PRODUTOS que é um iterable. Perceba que assim como vimos com a função ZIP, a função MAP nos retorna um OBJETO que precisa ser transformado em uma lista, assim como é realizado na última célula do jupyter.
def padronizar_texto(texto):
texto = texto.casefold()
texto = texto.replace(" ", " ")
texto = texto.strip()
return texto
• Agora queremos padronizar uma lista de códigos:
produtos = [' ABC12 ', 'abc34', 'AbC37', 'beb12', ' BSA151', 'BEB23']
produtos = map(padronizar_texto, produtos)
print(produtos)
___________________
<map object at 0x00000202D54F0AC0>
produtos = list(map(padronizar_texto, produtos))
print(produtos)
___________________
['abc12', 'abc34', 'abc37', 'beb12', 'bsa151', 'beb23']
Vamos olhar mais a fundo o que está ocorrendo dentro da função map do exemplo anterior. Veja a função MAP como uma espécie de linha de produção.
O que ela faz é pegar cada um dos itens do ITERABLE(no nosso caso a lista produtos) e passar esse item pela função indicada(nesse caso padronizar_texto). O resultado dessa linha de produção é um grande pacote de itens transformados em algo de acordo com a função indicada.
– Aplicando function em iterable no sort
Já conhecemos o método .sort() aplicável a listas. Quando usamos esse método para lista de strings por exemplo, a ordem não será alfabética e sim seguindo
a tabela ASCII. (exemplo ao lado)
O Python nos permite fornecer algum critério chave para que a ordem seja realizada.
Para isso usaremos o argumento key= dentro da nossa função .sort.
Key indica que um critério específico será fornecido. Nesse caso, casefold (letras minúsculas).
Perceba que foi necessário o str, pois casefold é um método de STRINGS
produtos = ['apple tv', 'mac', 'IPhone x', 'IPhone 11', 'IPad', 'apple watch', 'mac book', 'airpods']
produtos.sort()
print(produtos)
_____________________________
['IPad', 'IPhone 11', 'IPhone x', 'airpods', 'apple tv', 'apple watch', 'mac', 'mac book']
• Ordenado segundo a tabela ASCII
produtos.sort(key=str.casefold)
print(produtos)
____________________
['airpods', 'apple tv', 'apple watch', 'IPad', 'IPhone 11', 'IPhone x', 'mac', 'mac book']
– Lambda expressions
As lambda expressions são mais um conceito que não é obrigatório, mas é bem comum no mercado de trabalho e certamente irá surgir em códigos que você venha a ler no futuro. Ela funciona como uma versão simplificada da função que nós criamos usando def, etc... A Lambda é uma função Anônima. Ela não é chamada como as funções que vimos até agora. Ela é uma função local, que só funciona dentro de uma variável que definirmos.
Chamamos de anônima, pois não é necessário chamá-la como fazíamos com as funções “normais”. Antes de irmos para um exemplo, vamos entender sua estrutura.
variável = lambda parâmetro: expressão
• Variável que receberá os dados calculados.
• Indicação que será criada uma função lambda
• Equivalente aos argumentos indicados nos parênteses das funções: def nome_função (parâmetro)
• Equivalente as linhas de código dentro da indentação das funções: def minha_função(arg): expressão
Vamos analisar agora um exemplo real. O desafio é criar uma função que calcule o imposto devido, baseado no preço de um produto. Criamos uma função “normal” e uma lambda para que seja possível compará-las. Perceba que a função lambda nos permite declarar toda a função em apenas uma linha. No entanto, o mesmo resultado pode ser obtido usando a função convencional.
imposto = 0.3
#criando uma função "normal"
def preco_imposto(preco):
return preco * (1 + 0.3)
print(preco_imposto(100))
#criando uma função "lambda"
preco_imposto2 = lambda preco: preco * (1.0 + imposto)
print(preco_imposto2(100))
__________________
130.0
130.0
– A grande utilidade de Lambda Expressions
Nas aulas passadas vimos a função map e o método sort. Eles possuem um argumento que recebe uma função. Essa função normalmente é criada antes, para depois ser passada como parâmetro. Mas se a função for muito simples, você pode passar lambda
expressions como parâmetro. Então, a principal utilidade de lambda expressions está em não precisar criar uma função previamente para passá-la depois como parâmetro.
Agora vamos relembrar alguns métodos de dicionário e vamos ver alguns exemplos de aplicação usando o dicionário preco_tecnologia
preco_tecnologia = {'notebook asus': 2450, 'iphone': 4500, 'samsung galaxy': 3000, 'tv samsung': 1000, 'ps5': 3000, 'tablet': 1000, 'notebook dell': 3000, 'ipad': 3000, 'tv philco': 800, 'notebook hp': 1700}
print(preco_tecnologia)
____________________________
{'notebook asus': 2450, 'iphone': 4500, 'samsung galaxy': 3000, 'tv samsung': 1000, 'ps5': 3000, 'tablet': 1000, 'notebook dell': 3000, 'ipad': 3000, 'tv philco': 800, 'notebook hp': 1700}
print(preco_tecnologia.items())
________________________
dict_items([('notebook asus': 2450), ('iphone': 4500), ('samsung galaxy': 3000), ('tv samsung': 1000), ('ps5': 3000), ('tablet': 1000), ('notebook dell': 3000), ('ipad': 3000), ('tv philco': 800), ('notebook hp': 1700)])
print(preco_tecnologia.keys())
________________________
dict_keys(['notebook asus', 'iphone', 'samsung galaxy', 'tv samsung', 'ps5', 'tablet', 'notebook dell', 'ipad', 'tv philco', 'notebook hp'])
print(preco_tecnologia.values())
________________________
dict_values([2450, 4500, 3000, 1000, 3000, 1000, 3000, 3000, 800, 1700])
• Usando o map()
Neste primeiro exemplo, queremos saber o preço de cada produto do dicionário adicionando o valor do imposto de 30% sobre o valor do produto. Faremos de 2 formas: a primeira definindo uma função previamente, e a segunda passando uma lambda
expression como parâmetro.
#Fazendo por function
def calcular_preco(preco):
return preco * 1.3
preco_com_imposto = list(map(calcular_preco, preco_tecnologia.values()))
print(preco_com_imposto)
_______________________
[3185.0, 5850.0, 3900.0, 1300.0, 3900.0, 1300.0, 3900.0, 3900.0, 1040.0, 2210.0]
#fazendo por lambda
preco_com_imposto2 = list(map(lambda preco: preco * 1.3 , preco_tecnologia.values()))
print(preco_com_imposto2)
_______________________
[3185.0, 5850.0, 3900.0, 1300.0, 3900.0, 1300.0, 3900.0, 3900.0, 1040.0, 2210.0]
• Lembrando que o método values() nos dá uma lista somente com os valores do dicionário, que nesse caso é o que nos interessa para o cálculo.
A segunda função que veremos neste módulo é o FILTER. O FILTER filtra um iterable com a ajuda de uma função (passada como parâmetro) que testa todos os elementos do iterable e retorna somente aqueles elementos que satisfazem à condição da função de teste, ou seja, todos os elementos do iterable que fazem a função retornar True como resposta.
Função filter. O primeiro argumento é a função que testa se cada elemento do iterable (segundo argumento) satisfaz a uma condição
filter(função, iterable)
Lembrando que a função a ser passada como parâmetro fará uma comparação e deverá ter retorno booleano (True ou False). O resultado da função filter é um filter object.
Por isso, teremos que usar a seguinte estrutura:
lista = list(filter(função, iterable))
• Lista que receberá os dados após a aplicação da função FILTER
• Função List que transformará o resultado da função FILTER em uma lista
• Função filter. O primeiro argumento é a função, que testa se cada elemento do iterable (segundo argumento) satisfaz a uma condição
• Usando o filter()
Neste exemplo com filter, queremos apenas os produtos que custam acima de 2000. Faremos também de 2 formas: a primeira definindo uma função previamente, e a segunda passando uma lambda expression como parâmetro.
print(preco_tecnologia.items())
________________________
dict_items([('notebook asus': 2450), ('iphone': 4500), ('samsung galaxy': 3000), ('tv samsung': 1000), ('ps5': 3000), ('tablet': 1000), ('notebook dell': 3000), ('ipad': 3000), ('tv philco': 800), ('notebook hp': 1700)])
#fazendo por function
#print(preco_tecnologia.items())
def ehmaior2000(item):
return item[1] > 2000
produtos_acima2000 = dict(list(filter(ehmaior2000, preco_tecnologia.items())))
print(produtos_acima2000)
____________________
{'notebook asus': 2450, 'iphone': 4500, 'samsung galaxy': 3000, 'ps5': 3000, 'notebook dell': 3000, 'ipad': 3000}
#fazendo por lambda
produtos2_acima2000 = dict(list(filter(lambda item: item[1] > 2000 , preco_tecnologia.items())))
print(produtos2_acima2000)
____________________
{'notebook asus': 2450, 'iphone': 4500, 'samsung galaxy': 3000, 'ps5': 3000, 'notebook dell': 3000, 'ipad': 3000}
Lembrando que o método items() nos dá uma lista com as chaves e os valores do dicionário, que nesse caso é o que nos interessa , pois queremos saber todos os produtos que custam acima de 2000
– Lambda Expressions para criar um Construtor de Funções
Agora vamos ver mais uma aplicação de lamba expressions, que é criar um “gerador de funções”. Basicamente, quando criarmos uma função com def, usaremos lambda expressions dentro dela.
Um exemplo de aplicação de “gerador de funções” é criar uma função que permita calcular o valor acrescido de imposto de diferentes categorias (produto, serviço, royalties, etc). Considerando os seguintes impostos:
• Produtos = 0.1 (10%)
• Serviços = 0.15 (15%)
• Royalties = 0.25 (25%)
def calcular_imposto(imposto):
return lambda preco: preco * (1 + imposto)
# produto 0.1
#serviço 0.15
#royalties 0.25
calcular_preco_produto = calcular_imposto(0.1)
calcular_preco_servico = calcular_imposto(0.15)
calcular_preco_royalties = calcular_imposto(0.25)
• A função calcular_imposto() recebe imposto como parâmetro. E então o imposto é aplicado em uma função que recebe preco como parâmetro.
Como o retorno da função calcular_imposto é uma lambda expression, isso torna calcular_imposto um construtor de funções
• Cada uma dessas agora são funções que recebem preco como parâmetro e multiplica por (1 + imposto), onde o imposto de cada função está entre parênteses.
Agora vamos passar o valor 100 como parâmetro, e ver o que obtemos como resposta das funções que foram criadas.
print((calcular_preco_produto(100)))
print((calcular_preco_servico(100)))
print(calcular_preco_royalties(100))
__________________
110.00000000000001
114.99999999999999
125.0
Podemos ver que a resposta de cada função está de acordo com os impostos que definimos anteriormente para cada função. Perceba também que alguns números tiveram muitas casas decimais. Isto tem a ver com a forma como o computador armazena esses valores na memória.
Podemos corrigir isso usando a função round(), como na imagem ao lado.
print(round(calcular_preco_produto(100),2))
print(round(calcular_preco_servico(100),2))
print(round(calcular_preco_royalties(100),2))
___________________________
110.0 114.0 125.0
A aplicação de lambda expressions que vimos nesta aula é menos usual do que as formas que vimos anteriormente. Mas esta forma foi apresentada, pois em algum momento poder ser útil para você.
Nenhum comentário:
Postar um comentário