Nas aulas anteriores aprendemos como armazenar um valor, de qualquer tipo, em uma variável. Vimos também como isso é útil para organizarmos nosso código, torná-lo mais legível e, principalmente, para aproveitar resultados obtidos em etapas anteriores e reutilizá-los várias vezes durante nosso programa. Mas variáveis só podem ser usadas para referenciar um único valor. E se quiséssemos armazenar um conjunto de valores em uma mesma variável, de forma que pudéssemos acessá-los todos de uma só vez? Para isso recorremos a uma estrutura de dados nativa de Python, chamada lista.
Listas são representadas pelo tipo list, e permitem armazenar um conjunto de valores em uma única estrutura! Cada elemento ocupando uma posição dentro da lista é chamado de item (ou elemento). O número de itens que uma lista armazena é referido como seu comprimento. A princípio não há limites para o comprimento de uma lista, embora listas grandes demais certamente exigem mais recursos computacionais, podendo se tornar intratáveis. Outra característica importante das listas é que elas permitem armazenar itens de tipos diferentes dentro de uma mesma estrutura (embora seja mais usual armazenar itens do mesmo tipo). Podemos por exemplo armazenar dentro de uma única lista strings, booleanos, inteiros, floats, e até outras listas!
Na ilustração acima, temos uma lista de comprimento 5, armazenando itens de tipos diferentes. Cada item da lista ocupa um espaço próprio, representado como um "quadradinho". Os números abaixo de cada quadrado representam os índices de cada item na lista. Os índices nada mais são que endereços numéricos, que nos permitem referenciar elementos em cada posição na lista. Por exemplo, se quisermos nos referir ao número 42, indicaremos o índice (ou endereço) 2.
Obs: Em Python, a numeração dos índices começa em zero, e portanto o primeiro elemento se encontra na posição 0. Da mesma forma, o último item de uma lista de comprimento $n$ se encontra na posição $n-1$.
Após esta aula você deverá ser capaz de:
Existem algumas formas diferentes de se construir uma lista em Python. A mais simples consiste em inserir uma sequência de itens separados por vírgulas entre colchetes. Note que a ordem dos itens permanece a mesma em que foram inseridos durante s criação da lista.
Podemos também usar a função list
, passando como argumento uma sequência de números inteiros (ou range). Uma range pode ser criada usando a função range
.
A linguagem Python fornece outras formas mais eficientes de se criar listas, como o método de compreensão de listas. Mas para manter a simplicidade do material não abordaremos este método por enquanto. Fica apenas a referência para os mais curiosos.
Agora que temos uma lista, como acessar os elementos dentro dela? Existem basicamente duas formas: a indexação (indexing) e o recorte (slicing). Por fim, podemos usar também algumas funções aplicáveis a listas. Vejamos cada um deles.
Usando a notação de indexação [i]
podemos recuperar o elemento em determinada posição em uma lista. Para isso basta indicar o índice i
do elemento que queremos entre colchetes, ao lado da nossa lista (ou da variável que a armazena).
Se tentarmos passar um índice que não exista na lista (por exemplo o índice 9 em uma lista de comprimento 5), o interpretador encerrará a execução do programa e nos mostrará uma mensagem de erro.
Podemos usar números negativos para nos referir a elementos na lista seguindo uma lógica de ordem reversa. Por exemplo, podemos usar o índice -1 para nos referir ao último elemento, -2 ao penúltimo, e assim por diante.
Usando a notação de recorte [i:j]
podemos recuperar um conjunto de elementos de uma lista. A diferença para a indexação é que o recorte retorna uma sublista (um pedaço, ou slice da lista original), em vez de um único elemento. Para isso indicamos, entre colchetes e separados por dois pontos, dois números: o primeiro (i
) é o índice do elemento no começo do recorte; o segundo (j
) é o índice do elemento que delimita o fim do pedaço (não-inclusivo).
Podemos omitir o número i
ou j
se quisermos que o pedaço comece do primeiro elemento da lista ou que termine no último elemento da lista, respectivamente.
Embora pouco usual, podemos definir o passo do recorte alterando a notação de recorte para [i:j:k]
. Neste caso, k
é o tamanho do passo, ou seja, o número de elementos que devem ser pulados.
E se quisermos obter o elemento de maior ou menor valor dentro da lista? Para isso podemos usar as funções max
e min
, respectivamente.
A função reversed
espera receber uma lista e retorna uma nova lista com os elementos em ordem inversa.
Finalmente, podemos verificar se um elemento com determinado valor existe dentro de uma lista. Para isso, construímos uma expressão utilizando o operador in
. Caso o elemento exista na lista, a expressão retornará o valor booleano True
e, caso contrário, False
.
É possível construir listas facilmente a partir de outras. Para isso usamos o operador +
, que pode ser usado para concatenar listas. É importante que ambos os operandos sejam do mesmo tipo: lista.
Este operador é comumente usado para inserir novos elementos em uma lista. Mas lembre-se que listas só podem ser somadas a listas!
Ex 1. Você recebeu a seguinte tabela com dados de espécies coletadas pela sua turma na saída de Zoologia dos Vertebrados:
id | Localidade | Espécie | Nome comum | Contagem | Turma |
---|---|---|---|---|---|
0 | FAL | Ameiva ameiva | Calango | 4 | Zoovert 1/2018 |
1 | FAL | Phyllomedusa oreades | Perereca-arborícola | 2 | Zoovert 1/2018 |
2 | FAL | Artibeus sp. | Morcego | 4 | Zoovert 1/2018 |
3 | FAL | Athene cunicularia | Coruja-buraqueira | 5 | Zoovert 1/2018 |
4 | FAL | Hypostomus sp. | Peixe-cascudo | 7 | Zoovert 1/2018 |
5 | FAL | Cariama cristata | Seriema | 4 | Zoovert 1/2018 |
6 | JBB | Ameiva ameiva | Calango | 1 | Zoovert 1/2018 |
7 | JBB | Chrysocyon brachyurus | Lobo-guará | 1 | Zoovert 1/2018 |
8 | JBB | Cariama cristata | Seriema | 2 | Zoovert 1/2018 |
9 | IBGE | Bothrops neuwiedi | Jararaca | 1 | Zoovert 1/2018 |
(i) Armazene os nomes científicos das espécies coletadas em uma lista, e guarde a referência à lista em uma variável chamada especies
. Observe se as listas permitem armazenar mais de um elemento com um mesmo valor.
(ii) Usando a notação de slicing, obtenha três pedaços da lista especies
: o primeiro com as espécies coletadas na FAL, o segundo com as espécies coletadas no JBB e o terceiro com as espécies coletadas no IBGE. Armazene cada uma dessas sublistas em variáveis de nome especies_fal
, especies_jbb
e especies_ibge
, respectivamente.
(iii) Agora vamos guardar cada uma três listas de cada localidade em uma única estrutura!
Você deverá construir uma lista armazenando as três listas criadas no item anterior (cada uma por sua vez contendo nomes de espécies).
Armazene o resultado em uma variável chamada listas_especies
.
Em seguida, tente recuperar a lista de espécies para cada uma das localidades usando a variável que você acabou de criar.
(iv) Escreva uma função coletadaEm
, que recebe como argumentos:
Sua função deve retornar uma lista com os nomes das localidades em que a espécie passada como argumento ocorre. Em que localidades Cariama cristata ocorre? E Phyllomedusa oreades?
def coletadaEm( especie, listas_especies ):
res = [] # esta lista começa vazia, e deve ir sendo preenchida ao longo do código
# seu código aqui
return res
Ex 2. Em um levantamento florístico, você definiu um grid espacial de $5 \times 5$ células para registrar a ocorrência de espécies. Para cada espécie, armazenamos os dados em uma matriz da seguinte forma:
Os dados de ocorrência de Caryocar brasiliense (vulgo Pequi) foram registrados em uma lista de listas! Pare por um instante e tente entender como uma lista de listas pode ser usada para representar uma matriz.
# Apenas execute esta célula
grid_caryocar = [ [1,0,0,1,0],
[0,0,0,1,0],
[1,0,1,1,1],
[0,0,1,0,0],
[1,0,1,1,0] ]
Agora, seu desafio é acessar apenas os elementos da matriz acima em que a ocorrência de Caryocar brasiliense foi registrada (ou seja, os $1$s).