Compreensão de Compreensões de Lista em Python 3

Introdução

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

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

As compreensões de lista oferecem 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, as compreensões de lista podem ser preferidas 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 compreensões de lista são construídas assim:

Informação: Para seguir o exemplo de código deste tutorial, abra um shell interativo do Python no seu sistema local executando o comando python3. Então 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 ver 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 confirmar 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 for loop, 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 loop for então itera sobre o item, usando a variável letter na string iterável 'shark'. Dentro do loop for, cada item dentro da string é adicionado à lista com o método list.append(x).

A reescrita da compreensão de lista como um for loop nos fornece a mesma saída:

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

As compreensões de lista podem ser reescritas como for loops, e alguns for loops podem ser reescritos para serem compreensões de lista para tornar o código mais sucinto.

Usando Condicionais com Compreensões de Lista

Compreensões de lista podem utilizar declarações condicionais para modificar listas existentes ou outros tipos de dados sequenciais ao criar novas listas.

Vamos olhar um exemplo de uma declaração if usada em uma compreensão de lista:

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, assim como foram na seção acima, e agora é adicionada uma declaração if. A declaração if diz para adicionar apenas os itens que não são equivalentes à string 'octopus', então a nova lista apenas recebe os itens da tupla que não correspondem a 'octopus'.

Ao executarmos isso, notaremos 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 pela string que é excluída pela declaração condicional.

Vamos criar outro exemplo que usa operadores matemáticos, números 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á preenchida 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 entender 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.

Finalmente, podemos adicionar o operador para ter 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á 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, em seguida, 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 de loop for aninhado existente 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 na primeira lista pelos itens na segunda lista em cada iteração.

Para transformar isso em uma compreensão de lista, vamos condensar cada uma das linhas de código em uma linha, começando com a operação x * y. Isso será seguido pelo loop for externo e depois pelo loop for interno. Vamos adicionar um print() abaixo da nossa compreensão de lista para confirmar que a nova lista corresponde à lista que criamos com nosso bloco de loop for 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 pega os loops for aninhados e os achatam em uma linha de código, enquanto ainda cria exatamente a mesma lista para atribuir à variável my_list.

As compreensões de lista nos proporcionam uma maneira sucinta de criar listas, permitindo-nos destilar várias linhas de código em uma única linha. No entanto, vale a pena ter em mente que a legibilidade do nosso código deve sempre ter precedência, então 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 permitem-nos transformar uma lista ou outra sequência numa nova lista. Elas fornecem uma sintaxe concisa para completar esta tarefa, limitando as nossas linhas de código.

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

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

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