As funções lambda têm sido um método de programação funcional desde o Python 1.0. Entretanto, nos últimos anos, outras técnicas ganharam mais popularidade e substituíram amplamente os lambdas. No entanto, ainda há alguns usos especializados para lambdas que os programadores experientes em Python devem conhecer.

O que são funções lambda em Python?

Em Python, a função lambda refere-se a uma função anônima. O Python usa a lambda palavra-chave para criar uma função lambda. Uma expressão lambda consiste na palavra-chave lambda seguida de uma lista de argumentos, dois pontos e uma única expressão. A expressão é fornecida com os argumentos e avaliada quando a função lambda é chamada:

lambda argument: expression

As funções são uma construção de linguagem fundamental em quase todas as linguagens de programação e representam a menor unidade reutilizável de código. Normalmente, as funções em Python são definidas com a def palavra-chave. Como exemplo, mostraremos a função square que multiplica um número por ele mesmo:

# Define square function
def square(num):
    return num * num
# Show that it works
assert square(9) == 81
python

A def palavra-chave é uma forma bem conhecida de definir funções em Python, mas a linguagem também tem lambdas. Essas são funções anônimas que definem uma expressão com parâmetros. As lambdas podem ser usadas em qualquer lugar em que uma função seja esperada ou possa ser atribuída a um nome. Você pode ver a expressão lambda equivalente à função square aqui:

# Create square function
squared = lambda num: num * num
# Show that it works
assert squared(9) == 81
python
Nota

Em Python, a função lambda refere-se a uma função criada com a palavra-chave lambda . Lambda não é o nome de uma função específica nem é um dos operadores Python.

Qual é a diferença entre lambda e def?

Pode parecer estranho que o Python permita que você crie funções com ambos os termos lambda e def. No entanto, Lambda não é um recurso próprio **, mas apenas outra forma de criar funções curtas localmente. Toda função criada com lambda também pode ser criada com def. No entanto, esse não é o caso inverso.

No nível sintático, lambda e def são ambas palavras-chave. Uma diferença importante entre elas é a separação rígida entre declaração e expressão do Python ****. As declarações são etapas na execução do código, enquanto as expressões são avaliadas em um valor.

Def inicia uma instrução ou, mais especificamente, uma instrução composta, que contém outras instruções. Somente return declarações podem aparecer em uma def declaração. Um return statement retorna um valor quando a função definida com def é chamada.

Ao contrário da def statement, lambda inicia uma expressão que não pode conter nenhuma instrução. A expressão lambda recebe um ou mais argumentos e retorna uma função anônima. Quando a função lambda é chamada, a expressão contida nela é avaliada com os argumentos passados e é retornada.

Quais são as limitações das expressões lambda do Python?

O Python limitou propositalmente a utilidade das funções lambda, pois geralmente é melhor nomear as funções. Isso força os programadores a pensar sobre o significado da função e a distinguir claramente as partes.

Os lambdas não podem conter instruções, ao contrário do corpo de uma função definida com a def palavra-chave. Portanto, não é possível usar , if, for, etc. em uma função lambda. Também não é possível acionar uma exceção, pois isso requer uma declaração.

As funções lambda em Python podem conter uma única expressão que é avaliada quando chamada. Anotações de tipo não podem ser usadas dentro da expressão lambda. Atualmente, a maioria dos casos de uso de funções lambda em Python utiliza outras técnicas, como compreensões.

Diferentes usos das funções lambda em Python

As lambdas são derivadas da programação funcional. Em algumas linguagens, como JavaScript, as funções anônimas são amplamente usadas sem a necessidade de uma palavra-chave especial. No Python, as expressões lambda são usadas para criar pequenas funções localmente. Veremos suas aplicações mais úteis a seguir.

Como preencher funções de ordem superior em Python com lambdas

Os lambdas são frequentemente usados com funções de ordem superior como map(), filter() e reduce(). Os elementos de um iterável podem ser transformados sem o uso de loops graças aos lambdas. As funções de ordem superior são funções que recebem funções como parâmetros ou retornam uma função.

A função map() recebe uma função e um iterável como parâmetros. Ela executa a função para cada elemento do iterável. Vamos tentar gerar números quadrados. Usamos a map() função e passamos uma expressão lambda como argumento, o que gera a função square. A função quadrada é aplicada a cada elemento da lista com map():

nums = [3, 5, 7]
# Square numbers using `map()` and `lambda`
squares = map(lambda num: num ** 2, nums)
# Show that it works
assert list(squares) == [9, 25, 49]
python
Nota

A partir do Python 3.0, as funções map() e filter() retornam um iterável em vez de uma lista. Uma list() chamada é usada dentro das assert declarações para desempacotar iteráveis em uma lista.

As compreensões de lista oferecem uma abordagem mais moderna para o processamento de iteráveis. Em vez de recorrer a map() e gerar uma função lambda, podemos descrever a operação diretamente:

nums = [3, 5, 7]
# Square numbers using list comprehension
squares = [num ** 2 for num in nums]
# Show that it works
assert squares == [9, 25, 49]
python

A filter() função pode ser usada para filtrar os elementos de um iterável. Podemos estender nosso exemplo para gerar somente números quadrados pares:

# List of numbers 1-4
nums = [1, 2, 3, 4]
# Square each number
squares = list(map(lambda num: num ** 2, nums))
# Filter out the even squares
even_squares = filter(lambda square: square % 2 == 0, squares)
# Show that it works
assert list(even_squares) == [4, 16]
python

Mostramos a abordagem preferida de usar a compreensão de lista para gerar o mesmo resultado sem usar lambdas e funções de ordem superior. A if parte da compreensão é usada para filtrar os números pares dos números quadrados gerados:

# List of numbers 1-4 squared
squares = [num ** 2 for num in range(1, 5)]
# Filter out the even squares
even_squares = [square for square in squares if square % 2 == 0]
# Show that it works
assert even_squares == [4, 16]
python
Nota

A função reduce() do Python não foi incluída na biblioteca padrão desde o Python 3.0. Essa função pode ser encontrada no functools módulo.

Como implementar funções-chave em Python com lambdas

As compreensões substituíram amplamente as funções clássicas de ordem superior map() e filter() no Python. No entanto, as funções-chave podem ser usadas para demonstrar todos os pontos fortes dos lambdas.

As funções de comparação do Python sorted(), min() e max() operam em iteráveis. Cada elemento do iterável é submetido a uma comparação quando chamado. As três funções recebem uma função-chave como parâmetro opcional. A função de chave é chamada para cada elemento e retorna um valor de chave para a operação de comparação.

Vamos considerar o seguinte problema. Temos uma pasta com arquivos de imagem em que os nomes são mapeados para uma lista Python. Queremos classificar a lista. Todos os nomes de arquivos começam com img, seguido de um número:

# List of image file names
images = ['img1', 'img2', 'img30', 'img3', 'img22', 'img100']
python

Se usarmos a função sorted() do Python, a ordem lexicográfica será usada. Isso trata os dígitos consecutivos como números únicos. Assim, os números ['1', '2', '100'] são colocados na ordem ['1', '100', '2']. O resultado não é o esperado:

# Sort using lexicographic order
sorted_image = sorted(images)
# Show that it works
assert sorted_image == ['img1', 'img100', 'img2', 'img22', 'img3', 'img30']
python

Nós passamos uma lambda expressão que produz uma função-chave para garantir que a classificação esteja correta. A função key extrai a parte numérica de um nome de arquivo, que é usada como uma chave por sorted():

# Extract numeric component and sort as integers
sorted_image = sorted(images, key=lambda name: int(name[3:]))
# Show that it works
assert sorted_image == ['img1', 'img2', 'img3', 'img22', 'img30', 'img100']
python

A função de chave é usada localmente e apenas uma vez. Não é necessário definir uma função nomeada extra para ela. Lambdas são a maneira correta de criar funções-chave. Vamos dar uma olhada em mais dois exemplos.

Assim como sorted(), as funções integradas do Python min() e max() têm uma função-chave opcional. As funções localizam o menor e o maior elemento em uma lista ou outro iterável. O menor ou maior elemento é uma questão de definição e pode ser especificado usando a função key.

Está claro o que significa o menor ou o maior elemento para listas de valores simples, como uma lista de números. Não precisamos de uma função-chave especial nesse caso:

nums = [42, 69, 51, 13]
assert min(nums) == 13
assert max(nums) == 69
python
Nota

Se nenhuma função de chave for passada, a função de identidade f(x) = x será usada como padrão. Isso pode ser facilmente definido como um lambda Python com lambda x: x.

Mas e se cada elemento de um iterável incluir várias datas? Vamos imaginar uma lista de ditados que representam pessoas com seus nomes e idades. Qual é o critério para min() e max() decidir qual é o menor e o maior elemento? É nesse ponto que uma função-chave é útil.

Precisamos de dados de exemplo para ilustrar como as funções-chave funcionam. Vamos criar uma função Person() que sirva como um construtor:

# Constructor function for dict representing a person
def Person(name, age):
    return {'name': name, 'age': age}
# Check that it works as expected
assert Person('Jim', 42) == {'name': 'Jim', 'age': 42}
python

Nós criamos uma lista de pessoas usando nossa função construtora:

# Create list of people
people = [person('Jim', 42), person('Jack', 51), person('John', 69)]
python

Encontramos a pessoa mais velha usando a max() chamada. Isso gera uma função-chave usando a expressão lambda, que recebe um dict de pessoa e extrai a idade dele como um elemento de comparação:

# Find the oldest person
oldest = max(people, key=lambda person: person['age'])
# Check that it works
assert oldest == Person('John', 69)
python

A abordagem funciona exatamente da mesma forma para a função min() . Nesse caso, vamos definir a função-chave fora da min() chamada e usar uma expressão lambda novamente. Isso melhora a legibilidade e vale a pena se a função-chave tiver vários usos locais:

# Define key function to compare people by age
by_age = lambda person: person['age']
# Find the youngest person
youngest = min(people, key=by_age)
# Check that it works
assert youngest == Person('Jim', 42)
python

Como criar closures com lambdas Python

Os lambdas do Python também são usados para definir closures. São funções criadas por outras funções e que armazenam um valor. As closures podem ser utilizadas para criar famílias de funções semelhantes. Mostraremos um exemplo comum em que são criadas funções de potência.

As funções de potência recebem um argumento e o exponenciam. A função quadrada f(x) = x ^ 2 e a função cúbica f(x) = x ^ 3 são exemplos bem conhecidos. Funções de potência arbitrárias podem ser geradas como fechamentos usando uma função construtora. Usaremos uma expressão lambda, o que significa que não precisamos definir uma função interna nomeada:

# Define constructor function for power functions
def power(n):
    return lambda num: num ** n
# Create square and cubic functions as closures
square = power(2)
cubic = power(3)
# Show that it works
assert square(10) == 100
assert cubic(10) == 1000
python

Como usar a expressão de função imediatamente invocada (IIFE) com lambdas Python

O IIFE, pronunciado “iffy”, é um padrão conhecido em JavaScript. Ele envolve a definição de uma função anônima e sua execução imediata.

Lambdas podem ser usados como IIFEs, embora não sejam muito úteis devido às limitações do Python. Só precisamos colocar parênteses ao redor da expressão lambda:

(lambda num: num * num)
python

E outro par de parênteses contendo o argumento(s):

assert (lambda num: num * num)(3) == 9
python
Dica

Para iniciantes em Python, recomendamos dar uma olhada em nosso Tutorial de Python.

Este artigo foi útil?
Ir para o menu principal