Introdução à programação e aos algoritmos
5.2 Listas em Python
(endereço inicial) + (índice do elemento) × (tamanho do elemento
básico do vetor)
5.2 LISTAS EM PYTHON
Python não oferece diretamente uma estrutura de vetor, porém fornece algo ainda mais poderoso e cujo conceito você já conhece: listas.
O que é uma lista para você? Você pode fazer uma lista de músicas preferidas, ou de filmes a que já assistiu. Também pode fazer uma lista de suas notas em uma disciplina. Você pode fazer lista de qualquer coisa. Uma lista é simplesmente uma sequência de informações.
Para criar uma lista em Python, a sintaxe é simples: basta atribuir a um identificador uma lista de valores separados por vírgula e entre colchetes:
notas = [7, 8, 10, 9]
nomes = [‘José’, ‘João’, ‘Joaquim’]
Neste exemplo, a variável notas é uma lista com 4 notas e nomes é uma lista de 3 nomes representados por strings. Podemos facilmente manipular cada elemento colocando seu índice entre colchetes. Assim, notas[0] guarda o valor 7 e nomes[1] guarda o valor ‘João’.
Outra característica das listas em Python é que seus índices podem ser contados do final para o começo, bastando para isso usar valores negativos. Deste modo, o índice -1 corresponde ao último elemento de qualquer lista. No caso da lista notas, notas[-1] = notas[3] = 9, notas[-2] = notas[2] = 10, e assim
por diante (Figura 5.5).
Você também pode usar qualquer expressão inteira dentro dos colchetes para calcular o índice adequado. Por exemplo, notas[1+1] é o mesmo que notas[2] ou, se você tem uma variável i com valor inteiro, pode usar uma expressão inteira como notas[i+1] para ter acesso a um elemento. A restrição é que o resultado da expressão esteja dentro da faixa de índices válidos da lista. Mas, atenção, só valem expressões ou valores inteiros. Uma referência como notas[1.0] resultaria em erro, por tentar utilizar um valor (expressão) real como índice.
Figura 5.5 Índice progressivo e regressivo.
Podemos somar todos os valores de notas e encontrar a média
com um simples programa em Python:
notas = [7, 8, 10, 9]
soma = notas[0] + notas[1] + notas[2] + notas[3]
print(“A média é igual a “, soma / 4)
■ Programa 5.1: Programa notas.py.
É claro que esse programa não é prático. Por quê? Perceba que
para 4 notas você pode escrever rapidamente a referência a cada uma, mas... e se fossem 100 notas?
Para melhorar isso, podemos usar uma estrutura de repetição de
comandos, tornando o programa mais eficaz. Por exemplo, na Seção 3.6, usamos o comando range de Python para gerar números sequenciais. Desse modo, range(4) gera a sequência de números 0, 1, 2 e 3.
notas = [7, 8, 10, 9]
soma = 0
for i in range(4):
soma = soma + notas[i]
print(“A média é igual a “, soma / 4)
■ Programa 5.2: Programa notas_com_range.py
Dica 5.1 – Use a expressão de atribuição compacta quando possível.
Quando um identi cador aparece dos dois lados de uma expressão, como em
i = i + 1
Python possui uma forma mais compacta de escrevê-la:
i += 1
Dessa forma, as seguintes expressões são válidas:
i += 5 # Equivalente a i = i + 5
i -= 5 # Equivalente a i = i - 5
i *= 5 # Equivalente a i = i * 5
i /= 5 # Equivalente a i = i / 5
Na realidade, quando um identi cador aparecer dos dois lados de uma
expressão, indicando que estamos atualizando o seu valor, a expressão pode ser
simpli cada:
i += a # Equivalente a i = i + a
i -= a + b # Equivalente a i = i - (a + b)
i *= a - b # Equivalente a i = i * (a - b)
i /= a + 3 # Equivalente a i = i / (a + 3)
Note que quando a expressão à direita possui mais de um componente, é
tomada como uma expressão completa, indicando o uso de parênteses para avaliá-la
como um todo. Para comprovar, execute o Programa 5.3.
i = 5
j = i
a = 3
i = i * a + 2
j *= a + 2
print(‘i = ‘, i, ‘, j = ‘, j)
■ Programa 5.3: Programa de teste de atribuições.
Seu resultado será:
i = 17 , j = 25
No nal das contas, uma expressão do tipo i += 5 exige um
processamento mental mais curto que i = i + 5. Enquanto i = i +
5 seria pensado como “pegue o valor de i, some 5 e depois atribua a i”, i += 5
seria simplesmente “some 5 a i”.
Usando esta sintaxe, o Programa 5.2 caria:
notas = [7, 8, 10, 9]
soma = 0
for i in range(4):
soma += notas[i]
print(“A média é igual a “, soma / 4)
■ Programa 5.4: Programa notas_com_range.py usando atribuição
compacta.
No Programa 5.2, a variável i é usada como índice para notas.
Sucessivamente, assume um valor gerado por range().
Você notou algo peculiar? Pense sobre o comando for i in
range(4). A lista notas[] é uma sequência de valores, assim como range() . Se range(4) cria uma sequência e i vai assumir, sucessivamente, cada valor dessa sequência, podemos simplificar nosso programa criando uma variável nota e fazendo-a assumir cada valor da lista notas, sucessivamente. Veja o Programa 5.5.
notas = [7, 8, 10, 9]
soma = 0
for nota in notas:
soma += nota
print(“A média é igual a “, soma / 4)
■ Programa 5.5: Programa notas_com_lista.py
O resultado é absolutamente idêntico, com a vantagem de utilizar apenas a lista de notas.
Fato 5.2 – Listas em Python são vetores dinâmicos.
Uma lista de Python na realidade é um vetor com o diferencial de que seu tamanho é
dinâmico, ou seja, uma lista pode começar com zero elementos e ir crescendo de
acordo com a necessidade.
O interpretador Python encarrega-se de gerenciar o espaço de memória ocupado
pela lista. Em outras linguagens você deve saber o tamanho do vetor a priori, e
qualquer mudança em seu tamanho deve ser gerenciada pelo próprio programador.
Por conta da forma como Python gerencia sua memória, é útil usar um esquema
um pouco diferente para representar gra camente as listas. Imagine que uma lista seja
um relacionamento entre índices e valores. Pensando assim, cada índice “aponta” para
um valor dentro da memória do computador.
Figura 5.6 Lista notas.
Fato 5.3 – Listas são mutáveis.
Você pode modi car os valores de uma lista. No jargão de Python dizemos que a lista é
mutável, ou seja, seus valores podem ser mudados. Mas, você deve se lembrar que
inteiros são elementos imutáveis de Python, portanto, o que acontece? Neste caso
temos um elemento mutável apontando para um elemento imutável. Por exemplo, se
modi carmos o valor de um elemento de notas, o mapeamento da memória será
modi cado para apontar para outro valor. Veja o que acontece no trecho do Programa
5.6 na Figura 5.7.
notas = [7,8.1,10,9]
print(notas)
notas[3] = 6
print(notas)
■ Programa 5.6: Programa lista_mutavel.py
Figura 5.7 Lista notas mutável.
Como você deve ter percebido, uma lista pode conter outros
elementos, além de números. O Programa 5.7 apresenta outras possibilidades.
notas = [7, 8.1, 10.0, 9]
feira = [“banana”, “pera”, “couve”] notas_turma = [[7, 8.1, 10.0, 9], [5, 3, 10, 9.5]] vazia = []
print (notas)
print (feira)
print (notas_turma[0][2])
print (vazia)
print (feira[3])
■ Programa 5.7: Programa com listas diversas.
No programa, a lista notas contém quatro números, entre inteiros e reais e a lista feira contém três strings. Note que uma lista pode conter outras listas. A lista notas_turma contém duas listas de notas que poderiam ser usadas para representar cada uma as notas de um aluno diferente.
Repare a forma como um elemento deve ser referenciado em uma lista de listas. O comando print(notas_turma[0][2]) imprime o valor 10.0 que está na primeira lista (índice 0), na terceira posição (índice 2).
Por último, a lista vazia não contém nenhum elemento. O valor 5 da segunda lista seria referenciado por print(notas_turma[1] [0]).
A execução do programa vai bem até um último print. Se você o executar, o programa irá imprimir corretamente tudo até este ponto, quando deverá emitir a seguinte mensagem de erro:
IndexError: list index out of range
O que aconteceu foi que print(feira[3]) tentou imprimir um elemento que não existe. Lembre-se: os índices começam de zero, assim o último índice válido de feira é o 2. Modificando a linha para
print (feira[2])
a string couve será impressa corretamente.
Dica 2.6 – Crie Listas Homogêneas.
As listas não precisam conter necessariamente apenas um tipo de elemento. Você
pode misturar elementos de diferentes tipos. Mesmo que isto seja possível, preste
atenção: a lista deve ter coerência. Não é porque pode conter tudo que se vai colocar
tudo em uma mesma lista.
É razoável usar valores inteiros ou reais em uma lista chamada notas e
strings com nomes de alimentos em uma lista feira, mas colocar o nome do
aluno na lista notas não seria uma boa prática. No entanto, você pode ter uma
lista de nomes de alunos, e, no caso, esta lista conteria apenas cadeias de caracteres
(strings).
Resista à tentação de criar listas heterogêneas. No caso das notas de alunos, por
exemplo, poderia parecer mais simples criar uma lista de notas na qual o primeiro
elemento fosse o nome do aluno:
notas= [“Tércio Pacitti”, 10, 9, 9]
Este código funciona em Python, mas você tem de usar uma “regra” externa ao
programa que diz que o elemento de índice zero é o nome do aluno. Não há como
usar a sintaxe de Python para controlar isso. Não existe uma semântica associada ao
índice, e você será obrigado a documentar essa regra com um comentário. A
possibilidade de erro aumenta e é fácil esquecer de colocar um dos elementos.
Quando sentir necessidade de utilizar uma lista com elementos heterogêneos,
pre ra outra estrutura de Python: as tuplas (Seção 5.13). Em uma tupla, os índices
têm uma semântica associada, de modo que você possa dizer o que cada elemento
representa no mundo real.