Aula 09: Introdução a Listas
Objetivos de Aprendizagem
Ao final desta aula, você será capaz de:
- Criar listas em Python e acessar seus elementos por índice
- Aplicar fatiamento (slicing) para obter sublistas
- Utilizar os principais métodos de lista:
append,insert,remove,pop,sortereverse - Iterar sobre listas usando
forewhile - Reconhecer quando usar uma lista em vez de variáveis avulsas
Conteúdo Teórico
1. O que é uma Lista?
Até agora, cada variável armazenava um único valor: um número, um texto ou um booleano. Mas e quando precisamos guardar vários valores relacionados? Por exemplo: as notas de um aluno em seis provas, os dias da semana ou os produtos de um carrinho de compras.
Uma lista é uma estrutura de dados que armazena uma sequência ordenada de elementos em uma única variável. Em Python, listas são delimitadas por colchetes [] e os itens são separados por vírgulas.
# Uma variável para cada nota — problemático
nota1 = 7.5
nota2 = 8.0
nota3 = 6.5
# Uma lista com todas as notas — muito melhor
notas = [7.5, 8.0, 6.5, 9.0, 5.5, 7.0]
Uma lista em Python é uma coleção ordenada, mutável e que aceita elementos de tipos diferentes. "Ordenada" significa que a posição de cada elemento importa e é preservada. "Mutável" significa que podemos alterar o conteúdo após a criação.
Listas podem conter qualquer tipo de dado — inclusive misturado:
# Lista de strings
dias = ["segunda", "terça", "quarta", "quinta", "sexta"]
# Lista de inteiros
primos = [2, 3, 5, 7, 11, 13]
# Lista mista (válido em Python, use com cautela)
misto = [42, "Python", True, 3.14]
# Lista vazia
vazia = []
2. Acessando Elementos por Índice
Cada elemento de uma lista possui um índice (posição). Em Python, os índices começam em zero — o primeiro elemento está na posição 0, o segundo na posição 1, e assim por diante.
frutas = ["maçã", "banana", "laranja", "uva", "manga"]
#índices: 0 1 2 3 4
Para acessar um elemento, usamos o nome da lista seguido do índice entre colchetes:
frutas = ["maçã", "banana", "laranja", "uva", "manga"]
print(frutas[0]) # maçã
print(frutas[2]) # laranja
print(frutas[4]) # manga
Python também suporta índices negativos: -1 acessa o último elemento, -2 o penúltimo, e assim por diante:
print(frutas[-1]) # manga
print(frutas[-2]) # uva
Índices negativos são muito úteis quando você precisa acessar os últimos elementos de uma lista sem saber o tamanho dela.
Tamanho da lista com len()
A função len() retorna o número de elementos de uma lista:
frutas = ["maçã", "banana", "laranja", "uva", "manga"]
print(len(frutas)) # 5
O último índice válido é sempre len(lista) - 1:
ultimo = frutas[len(frutas) - 1] # "manga" — equivalente a frutas[-1]
3. Fatiamento (Slicing)
O fatiamento permite extrair uma parte de uma lista, criando uma nova lista com um subconjunto dos elementos.
A sintaxe é: lista[inicio:fim] — retorna os elementos do índice inicio até fim - 1 (o fim é exclusivo).
numeros = [10, 20, 30, 40, 50, 60, 70]
print(numeros[1:4]) # [20, 30, 40] — índices 1, 2 e 3
print(numeros[0:3]) # [10, 20, 30] — três primeiros
print(numeros[4:]) # [50, 60, 70] — do índice 4 até o fim
print(numeros[:3]) # [10, 20, 30] — do início até o índice 2
print(numeros[:]) # cópia completa da lista
Também é possível usar um passo (step): lista[inicio:fim:passo]
print(numeros[::2]) # [10, 30, 50, 70] — de dois em dois
print(numeros[::-1]) # [70, 60, 50, 40, 30, 20, 10] — invertida
4. Modificando Listas
Listas são mutáveis — podemos alterar seus elementos diretamente:
frutas = ["maçã", "banana", "laranja"]
frutas[1] = "morango" # substitui "banana" por "morango"
print(frutas) # ["maçã", "morango", "laranja"]
Métodos de lista
Métodos são funções associadas a um objeto. Para listas, os principais são:
| Método | O que faz | Exemplo |
|---|---|---|
append(x) | Adiciona x ao final | lista.append(10) |
insert(i, x) | Insere x na posição i | lista.insert(0, "início") |
remove(x) | Remove a primeira ocorrência de x | lista.remove("banana") |
pop(i) | Remove e retorna o elemento na posição i (padrão: último) | lista.pop() |
sort() | Ordena a lista no lugar (crescente por padrão) | lista.sort() |
reverse() | Inverte a lista no lugar | lista.reverse() |
index(x) | Retorna o índice da primeira ocorrência de x | lista.index("banana") |
count(x) | Conta quantas vezes x aparece | lista.count(5) |
clear() | Remove todos os elementos | lista.clear() |
notas = [7.5, 8.0, 6.5]
notas.append(9.0) # [7.5, 8.0, 6.5, 9.0]
notas.insert(0, 5.0) # [5.0, 7.5, 8.0, 6.5, 9.0]
notas.remove(5.0) # [7.5, 8.0, 6.5, 9.0]
ultimo = notas.pop() # remove 9.0; notas = [7.5, 8.0, 6.5]
notas.sort() # [6.5, 7.5, 8.0]
notas.sort(reverse=True) # [8.0, 7.5, 6.5]
notas.reverse() # [6.5, 7.5, 8.0]
5. Iterando sobre Listas
A forma mais direta de percorrer todos os elementos de uma lista é o laço for:
frutas = ["maçã", "banana", "laranja"]
for fruta in frutas:
print(fruta)
# maçã
# banana
# laranja
Quando você precisa do índice durante a iteração, use enumerate():
for i, fruta in enumerate(frutas):
print(f"{i}: {fruta}")
# 0: maçã
# 1: banana
# 2: laranja
Também é possível iterar com while usando o índice:
i = 0
while i < len(frutas):
print(frutas[i])
i += 1
Exemplo prático: Cálculo de média
notas = [7.5, 8.0, 6.5, 9.0, 5.5]
soma = 0
for nota in notas:
soma += nota
media = soma / len(notas)
print(f"Média: {media:.1f}") # Média: 7.3
Para somar todos os elementos de uma lista de números, Python oferece a função sum():
media = sum(notas) / len(notas)
6. Operações Úteis com Listas
# Verificar se um elemento está na lista
frutas = ["maçã", "banana", "laranja"]
print("banana" in frutas) # True
print("uva" in frutas) # False
# Concatenar listas com +
lista1 = [1, 2, 3]
lista2 = [4, 5, 6]
lista3 = lista1 + lista2 # [1, 2, 3, 4, 5, 6]
# Repetir uma lista com *
zeros = [0] * 5 # [0, 0, 0, 0, 0]
# Funções úteis para listas numéricas
numeros = [3, 1, 4, 1, 5, 9, 2, 6]
print(min(numeros)) # 1
print(max(numeros)) # 9
print(sum(numeros)) # 31
Demonstração em Aula
Os exemplos abaixo formam uma sequência para apresentação ao vivo. Cada bloco introduz um conceito novo construindo sobre o anterior — execute-os na ordem, preferencialmente no terminal interativo do Python (python3) ou em um arquivo .py.
Demo 1 — Por que precisamos de listas?
Mostre o problema de usar variáveis individuais e a solução imediata com uma lista.
# Sem lista: uma variável por nota — inviável para 30 alunos
nota_aluno1 = 8.5
nota_aluno2 = 6.0
nota_aluno3 = 9.5
# ... e assim até nota_aluno30 — imagine calcular a média disso!
# Com lista: todos os dados em uma única estrutura
notas_turma = [8.5, 6.0, 9.5, 4.0, 7.5, 8.0, 5.5, 9.0, 6.5, 7.0]
print(notas_turma)
print(f"Temos {len(notas_turma)} notas cadastradas")
Demo 2 — Indexação: acessando elementos por posição
filmes = ["Matrix", "Inception", "Interstellar", "Dune", "Arrival"]
#índice: 0 1 2 3 4
# Acesso por índice positivo
print(filmes[0]) # Matrix
print(filmes[2]) # Interstellar
# Índices negativos contam a partir do final
print(filmes[-1]) # Arrival — último
print(filmes[-2]) # Dune — penúltimo
# O que acontece com um índice fora do intervalo?
# print(filmes[10]) # IndexError — descomente para demonstrar o erro
Pergunte à turma: qual é o índice de "Inception"? E qual é o índice negativo equivalente?
Demo 3 — len() e a relação com os índices válidos
filmes = ["Matrix", "Inception", "Interstellar", "Dune", "Arrival"]
tamanho = len(filmes)
print(f"A lista tem {tamanho} elementos")
print(f"Índices válidos: 0 a {tamanho - 1}")
# O último índice válido é sempre len(lista) - 1
ultimo = filmes[tamanho - 1]
print(f"Último filme: {ultimo}") # equivalente a filmes[-1]
Demo 4 — Fatiamento (slicing): extraindo partes da lista
notas = [4.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5]
#índice: 0 1 2 3 4 5 6 7 8 9
# lista[inicio:fim] — fim é EXCLUSIVO
print(notas[0:3]) # [4.0, 5.5, 6.0] — primeiros 3
print(notas[7:]) # [8.5, 9.0, 9.5] — do índice 7 ao final
print(notas[:4]) # [4.0, 5.5, 6.0, 6.5] — do início até índice 3
# Com passo: lista[inicio:fim:passo]
print(notas[::2]) # [4.0, 6.0, 7.0, 8.0, 9.0] — posições pares
print(notas[::-1]) # lista invertida
Fatiamento nunca modifica a lista original — ele sempre cria uma nova lista.
Demo 5 — Listas são mutáveis: modificando elementos
compras = ["arroz", "feijão", "macarrão"]
print("Antes:", compras)
compras[1] = "lentilha" # substitui o elemento no índice 1
print("Depois:", compras)
# Contraste: strings são IMUTÁVEIS
texto = "Python"
# texto[0] = "J" # TypeError! Descomente para demonstrar a diferença.
Demo 6 — Métodos: construindo e editando uma lista dinamicamente
Execute linha a linha, imprimindo a lista após cada operação para visualizar a mudança.
playlist = []
playlist.append("Bohemian Rhapsody")
playlist.append("Hotel California")
playlist.append("Stairway to Heaven")
print("Após appends:", playlist)
playlist.insert(0, "Back in Black") # insere no início
playlist.insert(2, "Smells Like Teen Spirit")
print("Após inserts:", playlist)
playlist.remove("Hotel California") # remove por valor
print("Após remove:", playlist)
removida = playlist.pop() # retira e retorna o último
print(f"Removida: {removida}")
print("Após pop():", playlist)
Demo 7 — Ordenação: sort() vs sorted()
numeros = [42, 7, 19, 3, 88, 15]
# sort() modifica a lista original (in-place)
numeros.sort()
print("Crescente:", numeros) # [3, 7, 15, 19, 42, 88]
numeros.sort(reverse=True)
print("Decrescente:", numeros) # [88, 42, 19, 15, 7, 3]
# sorted() retorna uma NOVA lista; a original não é alterada
original = [42, 7, 19, 3, 88, 15]
nova = sorted(original)
print("Original:", original) # [42, 7, 19, 3, 88, 15] — intacta
print("Nova: ", nova) # [3, 7, 15, 19, 42, 88]
Demo 8 — Iteração: for simples e com enumerate()
linguagens = ["Python", "Java", "C", "JavaScript", "Rust"]
# Iteração simples: obtemos cada elemento diretamente
print("=== Linguagens ===")
for linguagem in linguagens:
print(f" - {linguagem}")
# enumerate(): fornece índice e valor juntos
print("\n=== Com numeração ===")
for i, linguagem in enumerate(linguagens):
print(f" {i + 1}. {linguagem}") # +1 para exibir a partir de 1
Demo 9 — Programa completo: análise de notas da turma
Reúne indexação, len(), sum(), max(), min() e iteração em um único programa coeso.
notas = [8.5, 4.0, 7.0, 9.5, 3.5, 6.0, 8.0, 5.5]
media = sum(notas) / len(notas)
maior = max(notas)
menor = min(notas)
acima_da_media = 0
for nota in notas:
if nota >= media:
acima_da_media += 1
print(f"Turma com {len(notas)} alunos")
print(f"Média : {media:.1f}")
print(f"Maior : {maior}")
print(f"Menor : {menor}")
print(f"Acima da média: {acima_da_media} aluno(s)")
Exercícios / Checkpoints
Checkpoint 1: Criação e acesso
Crie uma lista com os nomes de 5 colegas. Imprima o primeiro, o último e o elemento do meio usando indexação. Em seguida, imprima o tamanho da lista com len().
Checkpoint 2: Fatiamento
Dada a lista numeros = [5, 10, 15, 20, 25, 30, 35, 40], use fatiamento para obter:
- Os três primeiros elementos
- Os três últimos elementos
- Apenas os elementos nas posições pares (0, 2, 4, 6)
- A lista inteira invertida
Checkpoint 3: Métodos de lista
Parta de uma lista vazia produtos = [] e, usando métodos de lista, construa passo a passo a lista ["arroz", "feijão", "macarrão", "sal", "óleo"]. Depois: remova "sal", ordene alfabeticamente e imprima o resultado.
Checkpoint 4: Iteração com for
Escreva um programa que receba uma lista de preços [12.50, 8.99, 25.00, 5.75, 17.30] e imprima cada preço com 10% de desconto aplicado, no formato: "Preço original: R$ 12.50 → Com desconto: R$ 11.25".
Checkpoint 5: Análise conceitual
Explique com suas palavras: qual a diferença entre usar lista.sort() e a função sorted(lista)? Em que situação cada uma seria mais adequada? (Dica: experimente no Python e observe o que acontece com a lista original em cada caso.)
Checkpoint 6: Problema aplicado
Dado um cadastro de alunos representado por uma lista de notas: [8.5, 4.0, 7.0, 9.5, 3.5, 6.0, 8.0, 5.5], escreva um programa que calcule e imprima:
- A média da turma
- A maior nota
- A menor nota
- Quantos alunos estão acima da média
Situações Problema
As duas situações abaixo são para implementação em aula. Elas exigem a combinação de vários conceitos da aula — não há uma única solução certa. Incentive os alunos a experimentar, errar e discutir abordagens diferentes.
Situação Problema 1: Análise de Temperaturas com Detecção de Onda de Calor
Contexto: Uma estação meteorológica registrou as temperaturas diárias (em °C) de uma cidade ao longo de duas semanas. O departamento de saúde quer identificar períodos de risco para a população.
Código inicial:
temperaturas = [28.5, 31.2, 30.8, 33.1, 29.7, 27.3, 26.8,
32.4, 35.1, 34.9, 33.7, 31.5, 29.2, 28.1]
dias = ["Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom",
"Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"]
Tarefas:
- Calcule e exiba a temperatura média do período.
- Identifique o dia mais quente e o mais frio, exibindo o nome do dia e a temperatura.
- Liste todos os dias cuja temperatura ficou acima da média, no formato:
"Qui (semana 1): 33.1°C". - Detecte se houve alguma "onda de calor": três ou mais dias consecutivos com temperatura acima de 32°C. Se sim, informe quantos dias consecutivos foram e em qual dia começou.
Você precisará percorrer a lista com um índice e verificar temperaturas[i], temperaturas[i+1] e temperaturas[i+2] ao mesmo tempo. Cuidado com o limite do índice!
Saída esperada (aproximada):
Média do período: 30.9°C
Mais quente: Ter (semana 2) — 35.1°C
Mais frio : Dom (semana 1) — 26.8°C
Dias acima da média:
Qui (semana 1): 33.1°C
Seg (semana 2): 32.4°C
...
Onda de calor detectada! 4 dias consecutivos a partir de Seg (semana 2).
Ver solução
# Tarefa 1: temperatura média
media = sum(temperaturas) / len(temperaturas)
print(f"Média do período: {media:.1f}°C")
# Tarefa 2: dia mais quente e mais frio
indice_max = 0
indice_min = 0
for i in range(len(temperaturas)):
if temperaturas[i] > temperaturas[indice_max]:
indice_max = i
if temperaturas[i] < temperaturas[indice_min]:
indice_min = i
semana_max = "semana 1" if indice_max < 7 else "semana 2"
semana_min = "semana 1" if indice_min < 7 else "semana 2"
print(f"Mais quente: {dias[indice_max]} ({semana_max}) — {temperaturas[indice_max]}°C")
print(f"Mais frio : {dias[indice_min]} ({semana_min}) — {temperaturas[indice_min]}°C")
# Tarefa 3: dias acima da média
print("\nDias acima da média:")
for i in range(len(temperaturas)):
if temperaturas[i] > media:
semana = "semana 1" if i < 7 else "semana 2"
print(f" {dias[i]} ({semana}): {temperaturas[i]}°C")
# Tarefa 4: onda de calor — janela de 3 índices consecutivos
onda_detectada = False
for i in range(len(temperaturas) - 2):
if (temperaturas[i] > 32.0 and
temperaturas[i + 1] > 32.0 and
temperaturas[i + 2] > 32.0):
if i == 0 or temperaturas[i - 1] <= 32.0: # início de nova sequência
duracao = 3
while i + duracao < len(temperaturas) and temperaturas[i + duracao] > 32.0:
duracao += 1
semana = "semana 1" if i < 7 else "semana 2"
print(f"\nOnda de calor detectada! {duracao} dias consecutivos a partir de {dias[i]} ({semana}).")
onda_detectada = True
if not onda_detectada:
print("\nNenhuma onda de calor detectada no período.")
Situação Problema 2: Fila de Atendimento com Prioridade
Contexto: Uma UBS (Unidade Básica de Saúde) precisa gerenciar sua fila de atendimento. Clientes comuns entram no final da fila. Clientes com prioridade (idosos, gestantes, pessoas com deficiência) entram logo após o primeiro da fila — que já está sendo atendido e não pode ser deslocado.
Código inicial:
# Fila no início do dia — cada string é o nome do paciente
fila = ["Carlos", "Maria", "João", "Ana"]
# Operações a simular (execute na ordem):
# 1. "Paulo" chega e entra normalmente no final da fila
# 2. "Dona Rosa" tem prioridade — entra logo após o primeiro
# 3. "Carlos" (primeiro da fila) é chamado para atendimento; imprima: "Chamando: Carlos"
# 4. "Lucas" chega e entra normalmente
# 5. "Seu Antônio" tem prioridade — entra logo após o primeiro da fila atual
# 6. Exiba a fila final com a posição de cada pessoa (1ª, 2ª, 3ª...)
# 7. Informe quantas pessoas ainda aguardam atendimento
Tarefas:
- Simule cada operação acima usando os métodos corretos (
append,insert,pop). - Após cada operação, imprima o estado atual da fila (para facilitar a depuração).
- Exiba a fila final numerada e o total de pessoas aguardando.
- Extensão: adapte o programa para simular o atendimento de todos os pacientes na ordem correta, chamando-os um a um até a fila esvaziar.
Um paciente prioritário entra na posição 1 (índice 1) — não no início absoluto (índice 0), pois o primeiro já está sendo atendido.
Saída esperada (após todas as operações):
[Após Paulo entrar] : ['Carlos', 'Maria', 'João', 'Ana', 'Paulo']
[Após Dona Rosa] : ['Carlos', 'Dona Rosa', 'Maria', 'João', 'Ana', 'Paulo']
Chamando: Carlos
[Após Lucas entrar] : ['Dona Rosa', 'Maria', 'João', 'Ana', 'Paulo', 'Lucas']
[Após Seu Antônio] : ['Dona Rosa', 'Seu Antônio', 'Maria', 'João', 'Ana', 'Paulo', 'Lucas']
Fila atual:
1ª: Dona Rosa
2ª: Seu Antônio
3ª: Maria
...
Total aguardando: 7 pacientes
Ver solução
# 1. Paulo entra normalmente no final
fila.append("Paulo")
print(f"[Após Paulo entrar] : {fila}")
# 2. Dona Rosa tem prioridade — entra logo após o primeiro (índice 1)
fila.insert(1, "Dona Rosa")
print(f"[Após Dona Rosa] : {fila}")
# 3. Carlos (primeiro) é chamado para atendimento
chamado = fila.pop(0)
print(f"Chamando: {chamado}")
print(f"[Após Carlos sair] : {fila}")
# 4. Lucas entra normalmente
fila.append("Lucas")
print(f"[Após Lucas entrar] : {fila}")
# 5. Seu Antônio tem prioridade — entra logo após o primeiro atual
fila.insert(1, "Seu Antônio")
print(f"[Após Seu Antônio] : {fila}")
# 6. Fila final com posições
print("\nFila atual:")
for i, pessoa in enumerate(fila):
print(f" {i + 1}ª: {pessoa}")
# 7. Total aguardando
print(f"\nTotal aguardando: {len(fila)} paciente(s)")
# Extensão: atender todos os pacientes na ordem
print("\n--- Extensão: atendendo todos ---")
while fila:
chamado = fila.pop(0)
print(f"Chamando: {chamado}")
print("Fila vazia — atendimento encerrado.")
Resumo da Aula
Nesta aula, você aprendeu:
- Uma lista armazena uma sequência ordenada e mutável de elementos em Python
- Elementos são acessados por índice (iniciando em 0); índices negativos acessam do final
- Fatiamento (
lista[inicio:fim]) extrai sublistas sem modificar a original - Os principais métodos:
append,insert,remove,pop,sort,reverse - O laço
forpercorre cada elemento;enumerate()fornece índice e elemento juntos
Próxima aula: Dicionários — estrutura chave-valor para dados mais expressivos
Referências
Leitura Essencial
- Python Software Foundation. Built-in Types — Lists. Documentação oficial do Python.
Disponível em: docs.python.org/3/library/stdtypes.html#lists
- Referência completa de todos os métodos e comportamentos de listas.
- Forbellone, A. L. V.; Eberspächer, H. F. Lógica de Programação: A Construção de Algoritmos e Estruturas de Dados. 3ª ed. São Paulo: Pearson, 2005.
- Capítulo sobre vetores e estruturas sequenciais fundamenta a compreensão das listas.
Aprofundamento (Opcional)
- Lutz, M. Aprendendo Python. 5ª ed. São Paulo: O'Reilly Brasil, 2013.
- Capítulo sobre sequências aprofunda operações e idiomas avançados de listas.
- Python Software Foundation. List Comprehensions. Disponível em: docs.python.org/3/tutorial/datastructures.html#list-comprehensions
- Forma compacta e pythônica de criar listas. Tema para explorar após dominar o básico.