Listas abrangentes em Python

compreensao-1_abertura

Quando escrevi sobre os geradores em Python, citei rapidamente as listas abrangentes²  compreensão de listacomprehensive lists — para só depois dar conta de que nunca as havia citado, então, vamos lá…. Compreensão de lista  Lista abrangente é uma construção sintática disponível em Python¹ para a criação de novas listas baseadas em outras já existentes, de uma forma concisa e com inspiração  na teoria dos conjuntos

(¹) Outras linguagens como Clojure, Common LISP e Haskell também as implementam mas, talvez a mais conhecida delas seja o comando SELECT da linguagem SQL.

(²) Como citado pelo Guilherme Groke nos comentários, o uso do termo “compreensão” para traduzir a palavra comprehensive é um falso cognato, aliás espalhado por diversos lugares, daí o motivo da revisão do termo nesta publicação e, para facilitar a leitura, a partir deste ponto somente os títulos manterão a palavra original tachada.

Definindo uma compreensão de lista abrangente

Em Python, uma lista abrangente é definida com a seguinte sintaxe:

[ «expressão» for «variáveis» in  «iterável» if «condição» ]

Sendo «expressão» aquilo que produzirá cada item da nova lista «variáveis» a lista de variáveis recebidas do objeto «iterável» e, opcionalmente, «condição» contendo os critérios de validação para a inclusão, ou não, do item.

Um exemplo

Um exemplo bem simples para a criação de uma lista contendo os números inteiros entre zero e nove…

numero = []
for i in range(10):
    numeros.append(i)

Pode ser escrito de um modo bem mais enxuto como uma lista abrangente

numeros = [i for i in range(10)]

Aliás esta sintaxe é equivalente ao uso conjunto de map() e lambda em conjunto….

numeros = map(lambda i : i, range(10))

Em ambos os casos, o resultado será a mesma lista:

>>> numeros
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Ou seja, pensando na teoria dos conjuntos, um subconjunto do conjunto de números inteiros.

Acrescentando condições

É possível acrescentar uma condição de validação para os elementos da lista a ser criada. Seguindo ainda com o exemplo anterior, ao invés de qualquer número, apenas os pares…

numeros_pares = [i for i in range(10) if not i % 2]

Que cujo resultado:

>>> numeros_pares
[0, 2, 4, 6, 8]

Ou seja, o valor só será incluído na lista se o resto da divisão deste por 2 for zero — Em Python, o valor para False equivale a 0, daí não é necessário fazer “not i % 2 == 0” e, claro, para os números ímpares basta fazer o oposto e remover o “not” .

Aninhando…

Elas também podem ser aninhadas…

from random import randint
bloco_de_numeros = [
    [randint(0, j + 1) for i in range(5)] for j in range(5)
]

Produzindo uma lista contendo outra listas dentro dela:

>>> bloco_de_numeros
[
    [1, 0, 0, 1, 1],
    [0, 0, 0, 2, 1],
    [0, 1, 0, 0, 2],
    [3, 4, 1, 0, 2],
    [2, 2, 1, 3, 3]
]

O tópico deste assunto na documentação oficial da linguagem tem mais exemplos de listas abrangentes sendo usadas umas dentro das outras, eu preferi ficar apenas no exemplo básico… 🙂

Compreensão de Conjunto abrangente

O conjunto abrangente funciona da mesma maneira com o diferencial de produzir um conjunto³ — set — ao invés de uma lista. A diferença na sintaxe está justamente no uso de chaves ao invés de colchetes…

mensagem = "socorram-me subi no onibus em marrocos"
todas_as_consoantes = {i for i in mensagem if not i in "aeiou,- "}

Produzindo:

>>> todas_as_consoantes
set(['c', 'b', 'm', 'n', 's', 'r'])

Retornando apenas as consoantes presentes dentro da string removendo vogais, espaço e também os caracteres de pontuação.

(³) O conjunto é como um dicionário que contém apenas valores, logo, não possui repetições.

Conclusão

Como dito citado acima, tanto a lista quanto o conjunto abrangentes são uma forma resumida de criação destes tipos de dados. E claro, bom lembrar que há ainda a expressão geradora, que tem a mesma sintaxe delas, porém produzindo um objeto gerador, ao invés de uma lista ou conjunto.

Até!

2 comentários sobre “Listas abrangentes em Python

  1. Oi Giovanni… não sei se você sabe mas comprehensive é um falso cognato, a tradução não é compreensivo e sim abrangente… talvez a tradução seja abrangência de listas, ou listas abrangentes 😉

    Curtir

    • Pois é, eu fiquei muito inseguro sob que palavra utilizar e no final fui junto com os tópicos equivalentes da Wikipédia em português mesmo com o “compreensivo”. Mas gostei da palavra e, assim que possível, vou acrescentar uma correção.

      Curtir

Os comentários estão desativados.