Funções Lambda em Python

PythonBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá a usar funções lambda em Python. Começaremos entendendo o conceito de funções anônimas e a palavra-chave lambda, comparando-as com as definições de função tradicionais. Em seguida, você criará funções lambda simples com diferentes números de parâmetros.

O laboratório explorará ainda mais como usar funções lambda de forma eficaz com funções nativas (built-in) do Python, como sorted. Finalmente, discutiremos as melhores práticas para usar funções lambda para garantir que seu código seja legível e de fácil manutenção.

Entender Funções Anônimas e Lambda

Nesta etapa, introduziremos o conceito de funções anônimas em Python, focando na palavra-chave lambda. Funções anônimas são funções sem nome, oferecendo uma maneira concisa de definir funções simples de expressão única.

Em Python, geralmente definimos funções usando a palavra-chave def. Por exemplo, uma função que dobra um número se parece com isto:

def double(x):
    return x * 2

print(double(10))

Para funções pequenas como esta, lambda fornece uma sintaxe mais compacta. Vamos criar a mesma função usando lambda.

No explorador de arquivos do WebIDE à esquerda, localize e abra o arquivo ~/project/lambda_example1.py. Adicione o seguinte código a ele:

## Define a lambda function to double a number
double_lambda = lambda x: x * 2

## Call the lambda function and print the result
print(double_lambda(10))

A sintaxe é lambda argumentos: expressão. Os argumentos são as entradas, e a expressão é uma única operação que é avaliada e retornada. Note que não há a palavra-chave return; o retorno é implícito.

Salve o arquivo. Para executar o script, abra o terminal no WebIDE e execute o seguinte comando:

python3 ~/project/lambda_example1.py

Você deverá ver a saída no terminal.

20

Isso demonstra como uma função lambda pode ser atribuída a uma variável e chamada exatamente como uma função regular.

Criar Funções Lambda com Parâmetros Variados

As funções Lambda são flexíveis e podem ser definidas com zero, um ou múltiplos parâmetros. No entanto, elas estão sempre restritas a uma única expressão. Nesta etapa, exploraremos a criação de lambdas com diferentes números de parâmetros.

Primeiro, vamos criar uma função lambda que não aceita argumentos. Isso pode ser útil para definir uma constante ou uma ação simples e repetível.

Abra o arquivo ~/project/lambda_example2.py no explorador de arquivos. Adicione o seguinte código:

## Define a lambda function with no arguments
get_greeting = lambda: "Hello, World!"

## Call the lambda function and print the result
print(get_greeting())

Em seguida, vamos criar uma função lambda que aceita múltiplos argumentos. Definiremos uma lambda que soma dois números. Adicione este código ao mesmo arquivo lambda_example2.py:

## Define a lambda function that adds two numbers
add_numbers = lambda x, y: x + y

## Call the lambda function with two arguments and print the result
print(add_numbers(5, 3))

Salve o arquivo. Agora, execute o script a partir do terminal para ver ambas as saídas:

python3 ~/project/lambda_example2.py

O terminal exibirá os resultados de ambas as funções lambda.

Hello, World!
8

Isso mostra que as funções lambda podem lidar com diferentes configurações de parâmetros, tornando-as versáteis para várias tarefas simples.

Usar Lambda com a Função sorted()

Um dos casos de uso mais comuns para funções lambda é servir como uma função rápida e inline para funções de ordem superior (funções que aceitam outras funções como argumentos). Um exemplo principal é a função embutida sorted() do Python, que pode aceitar um argumento key. O key especifica uma função a ser chamada em cada elemento antes de fazer as comparações de ordenação.

Imagine que você tem uma lista de tuplas, onde cada tupla representa um produto e seu preço. Você deseja ordenar essa lista com base no preço.

Abra o arquivo ~/project/lambda_sorted.py no editor. Adicione o seguinte código:

## A list of tuples (product, price)
products = [('Laptop', 1200), ('Mouse', 25), ('Keyboard', 75)]

## Sort the list by price (the second element of each tuple) using a lambda function
sorted_products = sorted(products, key=lambda item: item[1])

## Print the sorted list
print(sorted_products)

Neste código, key=lambda item: item[1] diz à função sorted() para usar o segundo elemento (item[1], que é o preço) de cada tupla como o valor para a ordenação. Isso é muito mais conciso do que definir uma função separada com def.

Salve o arquivo e execute-o a partir do terminal:

python3 ~/project/lambda_sorted.py

Você verá a lista de produtos ordenada pelo preço em ordem crescente.

[('Mouse', 25), ('Keyboard', 75), ('Laptop', 1200)]

Este padrão é extremamente comum e útil para ordenar estruturas de dados complexas de maneira simples e legível.

Técnicas Avançadas de Lambda

Nesta etapa, exploraremos algumas maneiras um pouco mais avançadas de usar funções lambda, incluindo a definição de valores de parâmetro padrão e a invocação imediata de uma função lambda.

Assim como as funções regulares, as funções lambda podem ter parâmetros com valores padrão. Isso fornece um valor de fallback (reserva) se um argumento não for fornecido durante a chamada da função.

Abra o arquivo ~/project/lambda_advanced.py no editor. Adicione o seguinte código:

## Define a lambda function with a default parameter value
power = lambda base, exponent=2: base ** exponent

## Call the lambda function without the optional argument (uses default)
print(power(3))

## Call the lambda function with both arguments
print(power(3, 3))

Outra técnica interessante é definir e chamar imediatamente uma função lambda. Isso é conhecido como Expressão de Função Imediatamente Invocada (Immediately Invoked Function Expression - IIFE). Pode ser útil para criar uma função temporária de uso único para calcular um valor sem poluir o namespace.

Adicione o seguinte código ao arquivo lambda_advanced.py:

## Define and immediately invoke a lambda function to calculate a discounted price
price = 100
discount_percentage = 20
final_price = (lambda p, d: p * (1 - d / 100))(price, discount_percentage)

print(final_price)

Salve o arquivo e execute-o a partir do terminal:

python3 ~/project/lambda_advanced.py

A saída mostrará os resultados de ambos os exemplos.

9
27
80.0

Embora essas técnicas demonstrem a flexibilidade das lambdas, lembre-se de que a legibilidade é fundamental. Se a lógica se tornar complexa, uma função def padrão é frequentemente uma escolha melhor.

Melhores Práticas e Legibilidade

Nesta etapa final, discutiremos as melhores práticas para o uso de funções lambda. Embora as lambdas sejam uma ferramenta poderosa para escrever código conciso, elas devem ser usadas com critério para manter a legibilidade e a manutenibilidade.

Quando usar lambda:

  • Como argumentos para funções de ordem superior: Este é o caso de uso principal. Funções como sorted(), map() e filter() são candidatas perfeitas para lambdas.
  • Operações simples e curtas: Se a lógica couber de forma confortável e clara em uma única linha, uma lambda é uma boa escolha.

Quando evitar lambda:

  • Lógica complexa: Se você precisar de múltiplas instruções, lógica condicional complexa ou loops, use sempre uma função def.
  • Preocupações com legibilidade: Se uma expressão lambda for difícil de entender rapidamente, ela perde seu propósito. Uma função nomeada com um nome descritivo é melhor.
  • Reutilização: Se você precisar da mesma lógica em vários lugares, defina-a uma vez com def para seguir o princípio Não Se Repita (Don't Repeat Yourself - DRY).

Vejamos um bom exemplo legível que reforça o caso de uso de melhor prática. Abra o arquivo ~/project/lambda_best_practice.py e adicione o seguinte código:

## A list of dictionaries
students = [
    {'name': 'Alice', 'grade': 88},
    {'name': 'Bob', 'grade': 95},
    {'name': 'Charlie', 'grade': 72}
]

## A good use of lambda: sorting a list of dictionaries by a value
sorted_by_grade = sorted(students, key=lambda student: student['grade'])

print("Sorted by grade:", sorted_by_grade)

## For comparison, a more complex task is better with a named function.
## For example, if you needed to apply a curve and check for a minimum score,
## a 'def' function would be much clearer than a complex lambda.
def process_grade(student):
    curved_grade = student['grade'] * 1.05
    return max(curved_grade, 75) ## Ensure a minimum score

processed_grades = [process_grade(s) for s in students]
print("Processed grades:", processed_grades)

Salve o arquivo e execute-o:

python3 ~/project/lambda_best_practice.py

Você verá a saída:

Sorted by grade: [{'name': 'Charlie', 'grade': 72}, {'name': 'Alice', 'grade': 88}, {'name': 'Bob', 'grade': 95}]
Processed grades: [92.4, 99.75, 75.60000000000001]

A primeira parte mostra um uso claro e apropriado de lambda. A segunda parte ilustra um cenário onde uma função nomeada é mais adequada. Sempre priorize escrever código que seja fácil para você e para os outros lerem e entenderem.

Resumo

Neste laboratório, você aprendeu os fundamentos das funções lambda do Python. Você começou entendendo sua sintaxe e como elas diferem das funções padrão definidas com def. Você praticou a criação de lambdas com zero, um e múltiplos parâmetros, e viu como elas podem ser atribuídas a variáveis e chamadas.

Uma conclusão fundamental foi a aplicação prática das funções lambda como argumentos para funções de ordem superior (higher-order functions), particularmente com sorted() para definir a lógica de ordenação personalizada de forma concisa. Também exploramos técnicas avançadas, como parâmetros padrão e expressões de função invocadas imediatamente (Immediately Invoked Function Expressions - IIFE). Por fim, você revisou as melhores práticas para usar lambdas, enfatizando que, embora sejam poderosas para casos simples de uso único, a legibilidade e a manutenibilidade devem ser sempre a prioridade, favorecendo funções nomeadas para lógicas mais complexas.