Lista: estrutura sequencial indexada¶
Tópicos¶
Introdução¶
Até aqui, trabalhamos com variáveis simples, capazes de armazenar
apenas um tipo, como bool
, float
e int
.
Nessa aula introduziremos o conceito de lista (= tipo list
), uma estrutura
sequencial indexada muito utilizada e uma das principais estruturas
básicas do Python.
Uma lista (= list
) em Python é uma sequência ou coleção ordenada
de valores de qualquer tipo ou classe tais como int
, float
, bool
, str
e mesmo list
, entre outros.
Diariamente utilizamos listas para organizar informação, como a lista de coisas a fazer, lista de compras, lista de filmes em cartaz etc.
Existem várias maneiras de criarmos uma lista.
A maneira mais simples é envolver os elementos da
lista por colchetes ( [
e ]
).
Podemos criar a lista contendo os 5 primeiros
primos da seguinte maneira:
>>> primos = [2, 3, 5, 7, 11]
Podemos criar uma lista de vários objetos de tipos distintos:
>>> uma_lista = [11, "oi", 5.4, True]
>>> outra_lista = ["joão", "masculino", 15, 1.78, "brasileira", "solteiro"]
>>> fernanda = ["Fernanda", "Montenegro", 1929, "Central do Brasil", 1998, "Atriz", "Rio de Janeiro, RJ"]
Observe o uso de colchetes ([
, ]
) para marcar o início e o final
da lista, e os elementos separados por vígula.
Uma lista pode ser criada vazia, da seguinte forma:
>>> lista_vazia = []
Comprimento de uma lista¶
A função len()
retorna o comprimento (= o número de elementos ou objetos)
de uma lista:
>>> len(primos)
5
>>> len(uma_lista)
4
>>> len(outra_lista)
6
>>> len(fernanda)
7
>>> len(lista_vazia)
0
Índices¶
Cada valor na lista é identificado por um índice.
Dizemos que uma lista é uma estrutura sequencial indexada
pois os seus elementos podem ser acessados sequencialmente
utilizando índices.
O primeiro elemento da lista tem índice 0,
o segundo tem índice 1, e assim por diante.
Observe que, por começar pelo índice zero,
o último elemento da lista primos
, o número 11,
tem índice 4, sendo que essa lista tem comprimento 5.
Para acessar um elemento de uma lista usamos
o operador de indexação []
.
A expressão dentro dos colchetes especifica o índice.
O índice do primeiro elemento é 0.
O seguinte programa imprime os valores da lista primos
:
Simule a execução desse programa e observe que a variável i
recebe o
valor zero que corresponde ao primeiro índice e, enquanto o índice for
menor que o comprimento da lista (= len(primos)
),
o elemento de índice i
é impresso.
Índices negativos indicam elementos da direita para a esquerda ao invés de da esquerda para a direita.
Um erro comum em programas é a utilização de índices inválidos (= list index out of range):
Concatenação e Repetição¶
Nota sobre eficiência computacional
Por ser um curso introdutório, utilizaremos nesse curso apenas as operações de concatenação e fatiamento de listas. Nosso objetivo é empoderar os alunos para que eles possam entender, aprender e usar essas estruturas rapidamente em seus programas, independente da eficácia computacional dessas soluções, permitindo que o aluno mantenha foco no problema e não na linguagem. O custo computacional dessas soluções será abordado em cursos mais avançados.
Duas listas podem ser concatenadas utilizando o operador +
.
Nesse exemplo, a concatenação da lista um
com a lista dois
cria uma nova lista formada por cópias dos elementos da lista um
e
dois
.
Uma lista vazia é o elemento neutro da concatenação de listas:
O exemplo abaixo, concatena a lista um
três vezes:
Para concatenar uma lista repetidas vezes, podemos utilizar o operador
*
para multiplicar
uma lista por um inteiro:
Observe que, assim como o *
em operações aritméticas, o operador
de repetição *
de listas também é comutativo, assim como a
repetição de listas vazias resulta em uma lista vazia.
O operador de repetição *
é bastante útil para criar uma lista de
comprimento N
com valor inicial determinado como:
Fatias de um lista¶
Muitas vezes, ao invés de considerar a lista completa, é necessário consider apenas um pedaço contínuo da lista, que podemos definir por 2 índices que marcam o início e o fim desse pedaço, que chamamos de fatia da lista.
Em Python, uma fatia de uma lista é definida colando o ínicio e o fim entre colchetes, separados por :, como:
>>> primos = [2, 3, 5, 7, 11]
>>> primos[1:2]
[3]
>>> primos[2:4]
[5, 7]
>>> primos[:3] # observe que o início não precisa ser definido
[2, 3, 5]
>>> primos[3:] # observe que o fim não precisa definido
[7, 11]
>>> primos[:]
[2, 3, 5, 7, 11]
Observe que o intervalo é sempre fechado à esquerda (inclui o primeiro elemento na fatia) e aberto à direita (não inclui o último elemento). A operação de fatiamento devolve uma cópia do pedaço da lista definido pelo intervalo.
Referência versus cópia¶
Quando uma lista é atribuída a uma variável, dizemos que a variável passa a fazer uma referência a lista. Assim, várias variáveis com nomes distintos podem fazer referência a mesma lista.
Nesse exemplo, para que possamos trabalhar com a lista_2
sem
alterar os elementos da lista_1
, precisamos copiar a lista_1.
A forma mais comum para copiar uma lista é criando uma fatia da lista inteira como:
lista_1 = ["oi", 2, 3.14, True]
lista_2 = lista_1[:] # cria uma cópia da lista_1
lista_2[2] = 5
print(lista_1) # observe que o elemento lista_1[2] NÃO foi modificado
Comando for
¶
Vários problemas envolvendo listas requerem percorrer (varrer) todos
os elementos da lista, um a um, do início até o fim. Nesses casos,
podemos utilizar o comando for
:
Para usar o comando for
, você precisa definir uma variável que vai
receber o valor de um elemento da lista a cada iteração.
Nesse exemplo, a variável elemento
recebe o valor
de cada elemento da lista primos
, ou seja, primeiro o valor
2, depois 3, 5, e assim por diante, até 13. A repetição termina
quando o último elemento da lista primos
for utilizado.
Observe também que a varredura da lista pode ser feita usando o
comando while
. A sequência de índices válidos é gerada variando
a variável i de 0 até len(primos)
.
Muitas vezes é mais conveniente varrer uma lista usando uma variável que assume valores dentro do intervalo dos índices válidos. Com isso, temos mais poder e flexibilidade no acesso aos elementos da lista, como por exemplo, varrer a lista da direita para a esquerda, ou pegar apenas os elementos de índice par.
Nesses casos também, quando queremos ter controle sobre os índices,
é muito comum utilizar o comando for
em conjunto com a função
range()
. Basicamente, devemos chamar a função range()
para
que ela “devolva uma lista”
contendo os valores dos índices que queremos utilizar.
A função range()
recebe 3 parâmetros: início
, fim
e
passo
, que definem a sequência de números a ser criada. Modifique
o trecho de programa abaixo para ver como a função range se comporta
em conjunto com o for
:
Observe que, como na definição de intervalos em fatias de lista,
o intervalo de números cobertos pela função range()
é fechado
no início
e aberto no fim
.
Quando o passo desejado é 1 (um), o valor não precisa ser
passado a função range()
, como abaixo:
Para facilitar mais ainda a varredura de listas, quando o início
desejado é 0 (zero) e o passo 1 (um), você pode definir apenas o
fim
, como:
Nesse exemplo, usando a função len()
o final do intervalo a ser
gerado pela função range()
. Para saber mais sobre essa função, consulte a
documentação da função range().
Para verificar se você entendeu como funciona a função range()
,
modifique o inicio
, fim
e passo
no trecho de programa
abaixo para varrer a lista de forma reversa, ou seja, da direita para
a esquerda.
Exercícios com listas¶
Exercício 1¶
(exercício 1 da lista de exercícios sobre vetores).
Dados n > 0 e uma sequência com n números reais, imprimí-los na ordem inversa a da leitura.
Clique aqui para ver uma solução.
Exercício 3¶
Dados dois números naturais m
e n
e duas sequências ordenadas com m
e
n números inteiros, obter uma única sequência ordenada contendo todos
os elementos das sequências originais sem repetição.
Sugestão: Imagine uma situação real, por exemplo, dois fichários de uma biblioteca.
Exercício 4¶
Dados um número inteiro n
e uma sequência com n
números reais,
determinar a maior soma de um segmento da sequência (com pelo menos um elemento).
Um segmento é uma subsequência de números consecutivos.
Para n == 12
e a sequência
5 -2 -2 -7 3 14 10 -3 9 -6 4 1
a soma do segmento de soma máxima é 3+14+10-3+9 = 33
.