# Funções lambda do Python: funções anónimas no Python

Desde a versão 1.0 do Python, as funções lambda são utilizadas como **meio para a programação funcional**. Atualmente, a utilidade desta função foi amplamente substituída por outras técnicas. No entanto, ainda existem algumas áreas de uso especial que os programadores experientes em Python devem conhecer.

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

O termo **“função lambda” significa função anónima** em Python. Para criar uma função lambda, o Python utiliza a palavra-chave `lambda`. Uma expressão lambda consiste na palavra-chave `lambda` seguida de uma lista de argumentos, dois pontos e uma única expressão (“expression”). Assim que a função lambda é chamada, a expressão é fornecida com os argumentos e avaliada:

```none
lambda argument: expression
```

As funções são uma construção linguística fundamental de quase todas as linguagens de programação e representam a menor unidade de código reutilizável. Normalmente, as **funções em Python são definidas com a palavra-chave `def`**. Por exemplo, este também seria o caso da função square, que multiplica um número por si mesmo:

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

Além da forma mais conhecida de definir funções em Python usando a palavra-chave `def`, a linguagem reconhece as “lambdas”. Estas são funções curtas e **anónimas (ou seja, sem nome) que definem uma expressão com parâmetros**. Pode usar lambdas em qualquer lugar onde uma função seja esperada ou pode vinculá-las a um nome por meio de uma atribuição. Aqui está a expressão lambda equivalente à função square:

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

Nota Em Python, o termo “função lambda” refere-se a uma função criada com a palavra-chave lambda. Lambda não é o nome de uma função e também não é um dos operadores do Python.

### Qual é a diferença entre lambda e def?

À primeira vista, parece estranho que o Python reconheça duas formas de criar funções: `lambda` e `def`. Mas é preciso ter em conta que `lambda` **não é uma função propriamente dita, mas simplesmente uma notação diferente** para criar funções curtas localmente. Todas as funções criadas com `lambda` também podem ser criadas com `def`. No entanto, o inverso não é verdadeiro.

A nível sintático, tanto `lambda` como `def` são palavras-chave. Uma diferença entre ambas reside na **separação estrita que o Python faz entre sentenças («Statement») e expressões («Expression»)**. As sentenças são passos na execução do código, enquanto as expressões são avaliadas em relação a um valor.

Com `def` começa uma **instrução (concretamente uma «Compound Statement») que contém mais instruções**. Dentro da instrução `def`, e apenas aí, podem aparecer as instruções `return`. Após a chamada à função definida com `def`, uma instrução `return` devolve um valor.

Ao contrário da sentença `def`, **`lambda` inicia uma expressão que não deve conter nenhuma sentença**. A expressão lambda recebe um ou mais argumentos e retorna uma função anónima. Se a função lambda gerada for chamada, será feita uma avaliação da expressão contida com os argumentos passados e o resultado será retornado.

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

O Python limita especificamente a utilidade das funções lambda, pois geralmente é **melhor nomear as funções**. Isso obriga os programadores a pensar no significado da função e a distinguir claramente algumas partes das outras.

Ao contrário do corpo de uma função definida pela palavra-chave `def`, as lambdas não podem conter instruções. Portanto, **não é possível utilizar `if`, `for`, etc. dentro de uma função lambda**. Também não é possível lançar uma exceção (Exception), pois para isso é necessária a instrução `raise`.

As funções lambda em Python só podem conter uma única expressão que é avaliada após ser chamada. Dentro da expressão lambda, **não é possível utilizar anotações de tipo**. Atualmente, outras técnicas são utilizadas para a maioria dos casos de uso das funções lambda do Python. Especialmente nas compreensões.

## Para que servem as funções lambda do Python?

As lambdas **surgem da programação funcional**. Em algumas linguagens, como JavaScript, frequentemente são utilizadas funções anónimas sem uma palavra-chave especial. Em Python, as expressões lambda são utilizadas para criar pequenas funções localmente, sem grandes complicações. Mostramos-lhe os casos de utilização mais úteis.

### Equipar funções de ordem superior com lambdas em Python

As lambdas são frequentemente utilizadas em conexão com **funções de ordem superior, como `map()`, `filter()` e `reduce()`**. Com a sua ajuda, é possível transformar os elementos de um «iterável» sem utilizar loops. 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 como parâmetros uma função e um iterável e executa a função para cada elemento do iterável. Considere o problema de gerar números quadrados: usamos a função `map()` e **passamos como argumento uma expressão lambda, que gera a função quadrado**. Com `map()`, a função quadrado é aplicada a cada elemento da lista:

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

Nota A partir do Python 3.0, as funções `map()` e `filter()` retornam um iterável em vez de uma lista. Pode usar `list()` dentro da instrução `assert` para descompactar o iterável numa lista.

Com as compreensões de listas, existe agora uma **abordagem moderna e preferida para processar iteráveis**. Em vez de recorrer ao `map()` e criar uma função lambda, a operação pode ser descrita diretamente:

```python
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]
```

Com a função `filter()`, é possível filtrar os **elementos de um iterável**. Ampliamos o nosso exemplo para que apenas sejam gerados números quadrados pares:

```python
# 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]
```

Voltamos a mostrar a abordagem moderna e preferida de usar a compreensão de listas para gerar **o mesmo resultado sem usar lambdas ou funções de ordem superior**. Usamos a parte `if` da compreensão para filtrar os números pares dos números quadrados:

```python
# 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]
```

Nota A função `reduce()` do Python já não faz parte da biblioteca padrão desde o Python 3.0. Foi transferida para o módulo `functools`.

### Executar funções-chave com lambdas em Python

As compreensões substituíram em grande parte o uso das funções clássicas de ordem superior `map()` e `filter()` em Python. No entanto, com as “Key-Functions”, existe um **cenário de uso em que as lambdas mostram plenamente os seus pontos fortes**.

As funções de comparação do Python `sorted()`, `min()` e `max()` operam sobre iteráveis. Quando esta função é chamada, **cada elemento do iterável é comparado**. As três funções aceitam uma função chave como parâmetro opcional `key`. A função chave trata cada elemento e retorna um valor chave para a operação de comparação.

Como exemplo, considere o seguinte problema. Imagine que tem uma pasta com ficheiros de imagem cujos nomes estão numa lista Python. **Quer ordenar a lista**. Todos os nomes dos ficheiros começam por `img`, seguido de uma numeração:

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

Se utilizar a função `sorted()` do Python, **é utilizada a «ordem lexicográfica».** Isto significa que os dígitos consecutivos são tratados como números únicos. Desta forma, os números `['1', '2', '100']` são colocados na ordem `['1', '100', '2']`. Ou seja, o resultado não corresponde às expectativas:

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

Para que a ordem se adapte às suas necessidades, usamos uma expressão **`lambda` que cria uma função-chave**. Isso permite extrair a parte numérica de um nome de ficheiro para que `sorted()` a utilize como chave:

```python
# 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']
```

A função chave é utilizada apenas localmente e uma única vez. Não é necessário definir uma função com nome adicional para ela. **Por isso, as lambdas são o meio adequado para criar funções chave**. Vejamos outros dois exemplos.

Além de `sorted()`, as funções incorporadas do Python `min()` e `max()` aceitam uma função-chave opcional. As funções encontram o menor ou o maior elemento de uma lista ou outro iterável. **O que constitui exatamente o menor ou o maior elemento é uma questão de definição** e pode ser especificado pela função-chave.

Com listas de valores simples, por exemplo, uma lista de números, fica **claro o que se entende por elemento «menor» ou «maior».** Aqui não é necessária uma função-chave especial:

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

Nota Se nenhuma função chave for passada, a função de identidade `f(x) = x` é usada implicitamente. Ela pode ser facilmente definida como uma lambda Python com `lambda x: x`.

Mas o que acontece se os elementos de um iterável compreenderem várias datas cada um? Imagine uma lista de dicionários («dicts») que representam pessoas com nome e idade. De acordo com que critério **`min()` e `max()` devem decidir qual elemento é o menor ou o maior**? Para isso, utiliza-se exatamente a função chave.

Para ilustrar **como funcionam as funções principais, precisamos de dados de exemplo**. Portanto, crie uma função `Person()` que sirva como construtor:

```python
# 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}
```

Com a ajuda da função construtora, **crie uma lista de pessoas**:

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

Em seguida, procure a pessoa mais velha usando a chamada `max()`. Depois de realizar esta etapa, **é gerada uma função-chave** por meio de uma expressão lambda que pega um dicionário de pessoas e extrai dele a idade como elemento de comparação:

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

A abordagem é exatamente a mesma para a função `min()`. Aqui, é necessário **definir a função chave fora da chamada `min()`**, utilizando, novamente, uma expressão lambda. Isso melhora a legibilidade e vale a pena se a função chave tiver vários usos locais:

```python
# 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)
```

### Criação de closures com lambdas em Python

Outra **utilização das lambdas do Python é a definição das «closures»**, funções que são criadas por outras funções e armazenam um valor. As closures podem ser utilizadas, por exemplo, para criar famílias de funções semelhantes. A seguir, mostramos o exemplo habitual: criar funções de potência.

As funções de potência recebem um argumento e o elevam à potência. Exemplos conhecidos são a função quadrada `f(x) = x ^ 2` e a função cúbica `f(x) = x ^ 3`. Por meio de uma função construtora, é possível gerar qualquer função de potência como closure. Utilize uma expressão lambda e poupe-se assim de definir uma função interna com nome:

```python
# 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
```

### Expressão de função invocada imediatamente (IIFE) com lambdas em Python

IIFE, pronunciado «iffy», é um **padrão conhecido em JavaScript**. Define uma função anónima e executa-a imediatamente.

Embora não sejam muito úteis **em Python devido à sua restrição de uso, as lambdas podem ser utilizadas como IIFE**. Basta colocar parênteses em torno da expressão lambda:

```python
(lambda num: num * num)
```

Além disso, outro par de parênteses que contenham o argumento ou argumentos:

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

Dica Se quiser aprender mais sobre Python, recomendamos o nosso tutorial de Python.


This is a markdown version of: [https://www.ionos.com/pt-pt/digitalguide/paginas-web/desenvolvimento-web/funcoes-lambda-do-python/](https://www.ionos.com/pt-pt/digitalguide/paginas-web/desenvolvimento-web/funcoes-lambda-do-python/) for AI/LLM consumption.