segunda-feira, 23 de janeiro de 2017

Voltemos aos ciclos: as listas de compreensão

Já vimos antes o que são ciclos e o que são listas, e até podemos usar ciclos para gerar listas como se ilustra no programa seguinte:
lista = []
for i in 'palavra':
    lista += [i]
Bem, aproveito para apresentar um novo conjunto de atribuições: as atribuições aumentadas. Estas operações não atribuem um valor a uma variável; em vez disso, alteram o valor dessa variável com o que estiver à direita da atribuição. Uma maneira muito mais simples de explicar isto é a seguinte:
Atribuições aumentadas: 
a += ba = a + b
a -= ba = a - b
a *= ba = a * b
a /= ba = a / b
a //= ba = a // b
a %= ba = a % b
Assim, o que está à esquerda é equivalente ao que está à direita. Isto explica a última linha do programa. Vamos então ver o que são afinal essas listas de compreensão. Mais uma vez, um exemplo ilustra melhor o que quero dizer:
lista = [i for i in 'palavra']
Muito bem, o que está aqui faz o mesmo que o programa mais acima! Vamos por partes: o facto de envolver  o i for i in 'palavra' com [] quer dizer que vamos obter uma lista. Se tivéssemos {} ou () poderíamos obter conjuntos ou tuplos, respetivamente. De seguida, as listas de compreensão devem ter uma instrução for, para iterar os vários elementos que irão compor a lista (no caso acima, vai iterar as letras da cadeia de caracteres e colocar cada uma como elemento da lista final). E finalmente, o i antes do for indica o que se vai colocar em cada elemento.
Vamos supor agora que queríamos a lista dos quadrados dos primeiros 10 inteiros:
>>> quad = [i*i for i in range(1,11)]
>>> quad
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Repare agora o que ficou no início, i*i em vez de i.
Mas isto pode tornar-se mais complicado:
>>> mult = [i*j for i in [1,2,3] for j in [2,4,6]]
>>> mult
[2, 4, 6, 4, 8, 12, 6, 12, 18]
Repare que aqui temos dois ciclos e o que vai acontecer é que para cada iteração de i, vai multipicar-se por cada um dos j e preencher um elemento, resultando num total de 9 elementos, para este exemplo.
Um exemplo bastante ilustrativo que vem diretamente da documentação do Python:
>>> matriz = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]
>>> [[linha[i] for linha in matriz] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
O que são aqueles ... à esquerda? É quando o IDLE está a aceitar mais do que uma linha porque deteta que ainda não acabou tudo na primeira linha (o parêntesis reto não fechou). E repare que a matriz é uma lista com 3 listas no seu interior. O que o comando na segunda entrada faz é transpor a matriz: cria 4 listas, e cada lista vai ter os itens i das linhas da matriz. Muito bem pensado, não é?
Vamos complicar ainda mais um bocadinho:
>>> x = [i for i in range(10) if i%3 != 0]
>>> x
[1, 2, 4, 5, 7, 8]
O que aconteceu aqui? Agora adicionámos uma condição com if, e só se esta se verificar é que o elemento é incluído na lista. No exemplo acima, o número só é introduzido se não for um múltiplo de 3.
E vamos terminar com uma função curiosa:
>>> zip([1,2,3],[4,5,6])
<zip object at 0x0423B2D8>
>>> list(zip([1,2,3],[4,5,6]))
[(1, 4), (2, 5), (3, 6)]
>>> list(zip([1,2,3],[4,5,6],[7,8,9]))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Repare como faz uma espécie de transposição...  Na primeira linha serve para demonstrar como o comando zip() cria um objeto; para vermos o seu conteúdo temos de o converter em lista. E o que faz é pegar nos primeiros elementos das listas de argumento e juntá-los em tuplos. Voltaremos a este comando mais tarde!

Sem comentários:

Enviar um comentário