Compreensão de List Comprehensions no Python 3

Introdução

Compreensões de lista oferecem uma maneira sucinta de criar listas com base em listas existentes. Ao usar compreensões de lista, as listas podem ser construídas aproveitando qualquer iterável, incluindo strings e tuplas.

Sintaticamente, compreensões de lista consistem em um iterável contendo uma expressão seguida de uma cláusula for. Isso pode ser seguido por cláusulas adicionais de for ou if, então a familiaridade com loops for e declarações condicionais ajudará você a entender melhor as compreensões de lista.

As list comprehensions fornecem uma sintaxe alternativa para criar listas e outros tipos de dados sequenciais. Embora outros métodos de iteração, como loops for, também possam ser usados para criar listas, list comprehensions podem ser preferíveis porque podem limitar o número de linhas usadas no seu programa.

Pré-requisitos

Você deve ter o Python 3 instalado e um ambiente de programação configurado no seu computador ou servidor. Se você não tiver um ambiente de programação configurado, pode consultar os guias de instalação e configuração para um ambiente de programação local ou para um ambiente de programação no seu servidor apropriado para o seu sistema operacional (Ubuntu, CentOS, Debian, etc.)

Compreensões de Lista

Em Python, as list comprehensions são construídas da seguinte forma:

Informação: Para acompanhar o código de exemplo neste tutorial, abra um shell interativo do Python em seu sistema local executando o comando python3. Em seguida, você pode copiar, colar ou editar os exemplos adicionando-os após o prompt >>>.

list_variable = [x for x in iterable]

A list, or other iterable, is assigned to a variable. Additional variables that stand for items within the iterable are constructed around a for clause. The in keyword is used as it is in for loops, to iterate over the iterable.

Vamos dar uma olhada em um exemplo que cria uma lista com base em uma string:

shark_letters = [letter for letter in 'shark']
print(shark_letters)

Aqui, a nova lista é atribuída à variável shark_letters, e letter é usado para representar os itens contidos na string iterável 'shark'.

Para confirmarmos como a nova lista shark_letters se parece, chamamos para print() e recebemos a seguinte saída:

Output
['s', 'h', 'a', 'r', 'k']

A lista que criamos com a compreensão de lista é composta pelos itens na string 'shark', ou seja, uma string para cada letra.

As compreensões de lista podem ser reescritas como laços for, embora nem todo laço for possa ser reescrito como uma compreensão de lista.

Usando nossa compreensão de lista que criou a lista shark_letters acima, vamos reescrevê-la como um laço for. Isso pode nos ajudar a entender melhor como a compreensão de lista funciona.

shark_letters = []

for letter in 'shark':
    shark_letters.append(letter)

print(shark_letters)

Ao criar uma lista com um laço for, a variável atribuída à lista precisa ser inicializada com uma lista vazia, como está na primeira linha do nosso bloco de código. O laço for então itera sobre o item, usando a variável letter na string iterável 'shark'. Dentro do laço for, cada item dentro da string é adicionado à lista com o método list.append(x).

Rewriting the list comprehension as a for loop provides us with the same output:

Output
['s', 'h', 'a', 'r', 'k']

List comprehensions can be rewritten as for loops, and some for loops can be rewritten to be list comprehensions to make code more succinct.

Using Conditionals with List Comprehensions

List comprehensions can utilize conditional statements to modify existing lists or other sequential data types when creating new lists.

Let’s look at an example of an if statement used in a list comprehension:

fish_tuple = ('blowfish', 'clownfish', 'catfish', 'octopus')

fish_list = [fish for fish in fish_tuple if fish != 'octopus']
print(fish_list)

A compreensão de lista usa a tupla fish_tuple como base para a nova lista chamada fish_list. As palavras-chave for e in são usadas, como foram na seção acima, e agora uma declaração if é adicionada. A declaração if diz para adicionar apenas os itens que não são equivalentes à string 'octopus', então a nova lista só recebe itens da tupla que não correspondem a 'octopus'.

Ao executarmos isso, perceberemos que fish_list contém os mesmos itens de string que fish_tuple, exceto pelo fato de que a string 'octopus' foi omitida:

Output
['blowfish', 'clownfish', 'catfish']

Portanto, nossa nova lista possui todos os itens da tupla original, exceto a string que é excluída pela declaração condicional.

Vamos criar outro exemplo que usa operadores matemáticos, inteiros, e o tipo de sequência range().

number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)

A lista que está sendo criada, number_list, será populada com os valores ao quadrado de cada item no intervalo de 0 a 9 se o valor do item for divisível por 2. A saída é a seguinte:

Output
[0, 4, 16, 36, 64]

Para desmembrar um pouco mais o que a compreensão de lista está fazendo, vamos pensar no que seria impresso se estivéssemos apenas chamando x for x in range(10). Nosso pequeno programa e saída ficariam assim:

number_list = [x for x in range(10)]
print(number_list)
Output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Agora, vamos adicionar a declaração condicional:

number_list = [x for x in range(10) if x % 2 == 0]
print(number_list)
Output
[0, 2, 4, 6, 8]

A declaração if limitou os itens na lista final para incluir apenas aqueles que são divisíveis por 2, omitindo todos os números ímpares.

Por fim, podemos adicionar o operador para elevar cada x ao quadrado:

number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)

Então cada um dos números na lista anterior de [0, 2, 4, 6, 8] agora está elevado ao quadrado:

Output
[0, 4, 16, 36, 64]

Você também pode replicar declarações if aninhadas com uma compreensão de lista:

number_list = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
print(number_list)

Aqui, a compreensão de lista primeiro verificará se o número x é divisível por 3 e depois verificará se x é divisível por 5. Se x satisfizer ambos os requisitos, ele será impresso, e a saída é:

Output
[0, 15, 30, 45, 60, 75, 90]

Declarações condicionais if podem ser usadas para controlar quais itens de uma sequência existente são incluídos na criação de uma nova lista.

Loops Aninhados em uma Compreensão de Lista

Os loops aninhados podem ser usados para realizar várias iterações em nossos programas.

Desta vez, vamos revisar uma construção existente de for loop aninhado e trabalhar em direção a uma compreensão de lista.

Nosso código criará uma nova lista que itera sobre 2 listas e realiza operações matemáticas com base nelas. Aqui está nosso bloco de código de loop for aninhado:

my_list = []

for x in [20, 40, 60]:
	for y in [2, 4, 6]:
		my_list.append(x * y)

print(my_list)

Ao executarmos este código, recebemos a seguinte saída:

Output
[40, 80, 120, 80, 160, 240, 120, 240, 360]

Este código está multiplicando os itens da primeira lista pelos itens da segunda lista em cada iteração.

Para transformar isso em uma compreensão de lista, vamos condensar cada linha de código em uma linha, começando com a operação x * y. Isso será seguido pelo for loop externo e, em seguida, pelo for loop interno. Adicionaremos uma instrução print() abaixo de nossa compreensão de lista para confirmar que a nova lista corresponde à lista que criamos com nosso bloco de for loop aninhado acima:

my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6]]
print(my_list)
Output
[40, 80, 120, 80, 160, 240, 120, 240, 360]

Nossa compreensão de lista leva os for loops aninhados e os achatam em uma linha de código enquanto ainda criam a mesma lista para atribuir à variável my_list.

As compreensões de lista nos proporcionam uma maneira sucinta de criar listas, nos permitindo destilar várias linhas de código em uma única linha. No entanto, vale ressaltar que a legibilidade de nosso código sempre deve ter precedência, portanto, quando uma linha de compreensão de lista se torna muito longa ou difícil de manusear, pode ser melhor dividi-la em loops.

Conclusão

As compreensões de lista nos permitem transformar uma lista ou outra sequência em uma nova lista. Elas fornecem uma sintaxe concisa para realizar essa tarefa, limitando nossas linhas de código.

As compreensões de lista seguem a forma matemática da notação de construtor de conjunto ou compreensão de conjunto, então podem ser particularmente intuitivas para programadores com formação matemática.

Embora as compreensões de lista possam tornar nosso código mais sucinto, é importante garantir que nosso código final seja o mais legível possível, então linhas únicas de código muito longas devem ser evitadas para garantir que nosso código seja amigável ao usuário.

Source:
https://www.digitalocean.com/community/tutorials/understanding-list-comprehensions-in-python-3