Aula Completa sobre Listas em Python
1. Introdução às Listas
As listas são uma das estruturas de dados mais versáteis e
frequentemente utilizadas em Python. Ao contrário das tuplas, as listas
são **mutáveis**, o que significa que podemos modificar o seu conteúdo
após a criação.
Uma lista em Python é uma coleção ordenada de itens que pode conter
elementos de diferentes tipos de dados, incluindo números, strings, e
até mesmo outras listas. Esta flexibilidade torna as listas extremamente
úteis para uma ampla variedade de tarefas de programação.
As principais características das listas são:
1. **Ordenadas**: Os elementos mantêm uma ordem definida.
2. **Mutáveis**: Podemos adicionar, remover ou modificar elementos
após a criação.
3. **Indexáveis**: Podemos aceder aos elementos através de índices.
4. **Permitem duplicados**: O mesmo valor pode aparecer múltiplas
vezes.
Quando comparadas com as tuplas, a principal diferença é a
mutabilidade. Enquanto as tuplas são imutáveis e geralmente usadas
para dados que não devem mudar, as listas são ideais para coleções
dinâmicas que precisam ser modificadas durante a execução do
programa.
2. Criando Listas
Existem várias formas de criar listas em Python:
# Lista vazia
lista_vazia = []
print(f"Lista vazia: {lista_vazia}")
# Lista com elementos
numeros = [1, 2, 3, 4, 5]
print(f"Lista de números: {numeros}")
# Lista com diferentes tipos de dados
misturada = [1, "Python", 3.14, True]
print(f"Lista com tipos mistos: {misturada}")
# Usando o construtor list()
lista_de_string = list("Python") # Converte cada caractere em um
elemento
print(f"Lista a partir de string: {lista_de_string}") # ['P', 'y', 't', 'h', 'o',
'n']
# Lista a partir de uma tupla
tupla = (10, 20, 30)
lista_da_tupla = list(tupla)
print(f"Lista a partir de tupla: {lista_da_tupla}") # [10, 20, 30]
# Listas aninhadas (listas dentro de listas)
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(f"Matriz (lista aninhada): {matriz}")
3. Acedendo a Elementos de uma Lista
Podemos aceder aos elementos de uma lista usando indexação, que
começa em 0 para o primeiro elemento:
frutas = ["maçã", "banana", "laranja", "uva", "manga"]
# Indexação positiva (do início para o fim)
primeira_fruta = frutas[0] # maçã
terceira_fruta = frutas[2] # laranja
print(f"Primeira fruta: {primeira_fruta}, Terceira fruta: {terceira_fruta}")
# Indexação negativa (do fim para o início)
ultima_fruta = frutas[-1] # manga
penultima_fruta = frutas[-2] # uva
print(f"Última fruta: {ultima_fruta}, Penúltima fruta: {penultima_fruta}")
# Slicing (fatiamento) - obtendo sublistas
primeiras_tres = frutas[0:3] # ["maçã", "banana", "laranja"]
print(f"Primeiras três frutas: {primeiras_tres}")
do_inicio_ate_terceira = frutas[:3] # ["maçã", "banana", "laranja"]
print(f"Do início até a terceira: {do_inicio_ate_terceira}")
da_segunda_ate_o_fim = frutas[1:] # ["banana", "laranja", "uva",
"manga"]
print(f"Da segunda até o fim: {da_segunda_ate_o_fim}")
# Slicing com passo
de_dois_em_dois = frutas[::2] # ["maçã", "laranja", "manga"]
print(f"De duas em duas frutas: {de_dois_em_dois}")
# Lista invertida
invertida = frutas[::-1] # ["manga", "uva", "laranja", "banana", "maçã"]
print(f"Lista invertida: {invertida}")
# Acedendo a elementos em listas aninhadas
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
elemento_central = matriz[1][1] # 5
print(f"Elemento central da matriz: {elemento_central}")
4. Modificando Listas
A grande vantagem das listas sobre as tuplas é a capacidade de
modificação:
# Alterando elementos por índice
cores = ["vermelho", "verde", "azul"]
print(f"Lista original: {cores}")
cores[1] = "amarelo" # Substitui "verde" por "amarelo"
print(f"Lista após modificação: {cores}") # ["vermelho", "amarelo",
"azul"]
# Adicionando elementos
## append() - adiciona um elemento ao final da lista
cores.append("roxo")
print(f"Lista após append: {cores}") # ["vermelho", "amarelo", "azul",
"roxo"]
## insert() - insere um elemento numa posição específica
cores.insert(1, "verde") # Insere "verde" na posição 1
print(f"Lista após insert: {cores}") # ["vermelho", "verde", "amarelo",
"azul", "roxo"]
## extend() - adiciona elementos de outro iterável ao final
da lista
mais_cores = ["rosa", "preto"]
cores.extend(mais_cores)
print(f"Lista após extend: {cores}") # ["vermelho", "verde", "amarelo",
"azul", "roxo", "rosa", "preto"]
# Removendo elementos
## remove() - remove a primeira ocorrência de um valor
cores.remove("amarelo")
print(f"Lista após remove: {cores}") # ["vermelho", "verde", "azul",
"roxo", "rosa", "preto"]
## pop() - remove e retorna um elemento por índice (último
por padrão)
cor_removida = cores.pop(2) # Remove e retorna "azul"
print(f"Elemento removido: {cor_removida}")
print(f"Lista após pop: {cores}") # ["vermelho", "verde", "roxo", "rosa",
"preto"]
## del - remove um elemento ou fatia por índice
del cores[0] # Remove "vermelho"
print(f"Lista após del: {cores}") # ["verde", "roxo", "rosa", "preto"]
## clear() - remove todos os elementos
cores_backup = cores.copy() # Fazemos uma cópia para demonstrar
clear()
cores.clear()
print(f"Lista após clear: {cores}") # []
print(f"Backup da lista: {cores_backup}") # ["verde", "roxo", "rosa",
"preto"]
# Copiando listas
## Cópia superficial
numeros = [1, 2, [3, 4]]
copia_superficial = numeros.copy() # ou list(numeros) ou numeros[:]
print(f"Original: {numeros}, Cópia superficial: {copia_superficial}")
## Demonstrando o problema da cópia superficial com listas aninhadas
numeros[2][0] = 30 # Modifica a lista aninhada
print(f"Original após modificação: {numeros}") # [1, 2, [30, 4]]
print(f"Cópia superficial após modificação do original:
{copia_superficial}") # [1, 2, [30, 4]]
## Cópia profunda
import copy
numeros = [1, 2, [3, 4]]
copia_profunda = copy.deepcopy(numeros)
numeros[2][0] = 30 # Modifica a lista aninhada
print(f"Original após modificação: {numeros}") # [1, 2, [30, 4]]
print(f"Cópia profunda após modificação do original: {copia_profunda}")
# [1, 2, [3, 4]]
5. Operações Comuns com Listas
# Concatenação (+)
lista1 = [1, 2, 3]
lista2 = [4, 5, 6]
concatenada = lista1 + lista2
print(f"Listas concatenadas: {concatenada}") # [1, 2, 3, 4, 5, 6]
# Repetição (*)
repetida = [0] * 5
print(f"Lista repetida: {repetida}") # [0, 0, 0, 0, 0]
# Verificação de pertença (in, not in)
numeros = [10, 20, 30, 40, 50]
print(f"30 está na lista? {30 in numeros}") # True
print(f"60 não está na lista? {60 not in numeros}") # True
# Iteração sobre listas
frutas = ["maçã", "banana", "laranja"]
print("Iterando sobre a lista de frutas:")
for fruta in frutas:
print(f" - {fruta}")
# Iteração com índice usando enumerate
print("Iterando com índice:")
for indice, fruta in enumerate(frutas):
print(f" {indice}: {fruta}")
# Compreensão de listas (list comprehension)
quadrados = [x**2 for x in range(1, 6)]
print(f"Quadrados de 1 a 5: {quadrados}") # [1, 4, 9, 16, 25]
# Compreensão com condicionais
pares = [x for x in range(10) if x % 2 == 0]
print(f"Números pares de 0 a 9: {pares}") # [0, 2, 4, 6, 8]
6. Métodos de Listas
Python oferece vários métodos embutidos para manipular listas:
# Criando uma lista para demonstrar os métodos
numeros = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"Lista original: {numeros}")
# append() - adiciona um elemento ao final
numeros.append(7)
print(f"Após append(7): {numeros}") # [3, 1, 4, 1, 5, 9, 2, 6, 7]
# extend() - adiciona elementos de outro iterável
numeros.extend([8, 9])
print(f"Após extend([8, 9]): {numeros}") # [3, 1, 4, 1, 5, 9, 2, 6, 7, 8, 9]
# insert() - insere um elemento numa posição específica
numeros.insert(2, 10) # Insere 10 na posição 2
print(f"Após insert(2, 10): {numeros}") # [3, 1, 10, 4, 1, 5, 9, 2, 6, 7, 8,
9]
# remove() - remove a primeira ocorrência de um valor
numeros.remove(1) # Remove o primeiro 1
print(f"Após remove(1): {numeros}") # [3, 10, 4, 1, 5, 9, 2, 6, 7, 8, 9]
# pop() - remove e retorna um elemento por índice
elemento = numeros.pop(3) # Remove e retorna o elemento no índice 3
print(f"Elemento removido com pop(3): {elemento}")
print(f"Após pop(3): {numeros}") # [3, 10, 4, 5, 9, 2, 6, 7, 8, 9]
# pop() sem argumentos remove o último elemento
ultimo = numeros.pop()
print(f"Último elemento removido: {ultimo}")
print(f"Após pop(): {numeros}") # [3, 10, 4, 5, 9, 2, 6, 7, 8]
# index() - retorna o índice da primeira ocorrência
indice = numeros.index(5)
print(f"Índice do valor 5: {indice}") # 3
# count() - conta ocorrências de um valor
ocorrencias = numeros.count(3)
print(f"Ocorrências do valor 3: {ocorrencias}") # 1
# sort() - ordena a lista no local
numeros.sort()
print(f"Após sort(): {numeros}") # [2, 3, 4, 5, 6, 7, 8, 9, 10]
# sort() com reverse=True - ordena em ordem decrescente
numeros.sort(reverse=True)
print(f"Após sort(reverse=True): {numeros}") # [10, 9, 8, 7, 6, 5, 4, 3,
2]
# reverse() - inverte a ordem dos elementos
numeros.reverse()
print(f"Após reverse(): {numeros}") # [2, 3, 4, 5, 6, 7, 8, 9, 10]
# clear() - remove todos os elementos
numeros_backup = numeros.copy() # Fazemos uma cópia para
continuar o exemplo
numeros.clear()
print(f"Após clear(): {numeros}") # []
# Restaurando a partir do backup para continuar
numeros = numeros_backup.copy()
print(f"Lista restaurada: {numeros}") # [2, 3, 4, 5, 6, 7, 8, 9, 10]
# copy() - cria uma cópia superficial
copia = numeros.copy()
print(f"Cópia da lista: {copia}") # [2, 3, 4, 5, 6, 7, 8, 9, 10]
7. Funções Embutidas Úteis com Listas
# Criando uma lista para demonstrar as funções
numeros = [4, 2, 9, 7, 5, 1, 8, 3, 6]
print(f"Lista: {numeros}")
# len() - retorna o número de elementos
tamanho = len(numeros)
print(f"Tamanho da lista: {tamanho}") # 9
# max() - retorna o maior elemento
maior = max(numeros)
print(f"Maior valor: {maior}") # 9
# min() - retorna o menor elemento
menor = min(numeros)
print(f"Menor valor: {menor}") # 1
# sum() - retorna a soma dos elementos
soma = sum(numeros)
print(f"Soma dos valores: {soma}") # 45
# sorted() - retorna uma nova lista ordenada
ordenada = sorted(numeros)
print(f"Lista ordenada (nova): {ordenada}") # [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(f"Lista original (não modificada): {numeros}") # [4, 2, 9, 7, 5, 1, 8,
3, 6]
# sorted() com reverse=True
decrescente = sorted(numeros, reverse=True)
print(f"Lista em ordem decrescente: {decrescente}") # [9, 8, 7, 6, 5, 4,
3, 2, 1]
# any() - retorna True se pelo menos um elemento for
verdadeiro
tem_par = any(n % 2 == 0 for n in numeros)
print(f"Tem pelo menos um número par? {tem_par}") # True
# all() - retorna True se todos os elementos forem
verdadeiros
todos_positivos = all(n > 0 for n in numeros)
print(f"Todos os números são positivos? {todos_positivos}") # True
# enumerate() - retorna pares (índice, valor)
print("Usando enumerate():")
for i, valor in enumerate(numeros[:3]): # Limitando a 3 elementos para
o exemplo
print(f" Índice {i}: {valor}")
# zip() - combina elementos de múltiplas listas
nomes = ["Ana", "Bruno", "Carlos"]
idades = [25, 30, 22]
print("Usando zip():")
for nome, idade in zip(nomes, idades):
print(f" {nome} tem {idade} anos")
8. Compreensão de Listas (List Comprehension)
A compreensão de listas é uma forma concisa e elegante de criar novas
listas a partir de iteráveis existentes:
# Sintaxe básica: [expressão for item in iterável]
numeros = [1, 2, 3, 4, 5]
# Criando uma lista com o dobro de cada número
dobros = [x * 2 for x in numeros]
print(f"Dobros: {dobros}") # [2, 4, 6, 8, 10]
# Compreensão com condicionais
# Sintaxe: [expressão for item in iterável if condição]
pares = [x for x in range(1, 11) if x % 2 == 0]
print(f"Números pares de 1 a 10: {pares}") # [2, 4, 6, 8, 10]
# Compreensão com if-else
# Sintaxe: [expressão_if if condição else expressão_else for item in
iterável]
paridade = ["par" if x % 2 == 0 else "ímpar" for x in range(1, 6)]
print(f"Paridade dos números de 1 a 5: {paridade}") # ['ímpar', 'par',
'ímpar', 'par', 'ímpar']
# Compreensão aninhada (equivalente a loops for
aninhados)
# Sintaxe: [expressão for item1 in iterável1 for item2 in iterável2]
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
elementos = [x for linha in matriz for x in linha]
print(f"Elementos da matriz: {elementos}") # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Criando uma matriz com compreensão aninhada
matriz_2x3 = [[i * 3 + j + 1 for j in range(3)] for i in range(2)]
print(f"Matriz 2x3: {matriz_2x3}") # [[1, 2, 3], [4, 5, 6]]
# Comparação com loop tradicional
quadrados_loop = []
for x in range(1, 6):
quadrados_loop.append(x ** 2)
print(f"Quadrados (loop): {quadrados_loop}") # [1, 4, 9, 16, 25]
# Mesmo resultado com compreensão de lista
quadrados_comp = [x ** 2 for x in range(1, 6)]
print(f"Quadrados (compreensão): {quadrados_comp}") # [1, 4, 9, 16,
25]
9. Casos de Uso Comuns para Listas
As listas são extremamente versáteis e podem ser usadas em muitos
cenários:
# 1. Armazenamento de coleções de itens relacionados
alunos = ["Ana", "Bruno", "Carlos", "Diana", "Eduardo"]
notas = [85, 92, 78, 95, 88]
# 2. Implementação de pilhas (LIFO - Last In, First Out)
pilha = []
print("Operações de pilha:")
pilha.append("A") # Empilha A
pilha.append("B") # Empilha B
pilha.append("C") # Empilha C
print(f" Pilha atual: {pilha}") # ['A', 'B', 'C']
item = pilha.pop() # Desempilha (remove e retorna o último elemento)
print(f" Item desempilhado: {item}") # C
print(f" Pilha após desempilhar: {pilha}") # ['A', 'B']
# 3. Implementação de filas (FIFO - First In, First Out)
fila = []
print("\nOperações de fila:")
fila.append("A") # Enfileira A
fila.append("B") # Enfileira B
fila.append("C") # Enfileira C
print(f" Fila atual: {fila}") # ['A', 'B', 'C']
item = fila.pop(0) # Desenfileira (remove e retorna o primeiro
elemento)
print(f" Item desenfileirado: {item}") # A
print(f" Fila após desenfileirar: {fila}") # ['B', 'C']
# 4. Manutenção de históricos
historico_pesquisas = []
historico_pesquisas.append("Python tutorial")
historico_pesquisas.append("Como usar listas em Python")
historico_pesquisas.append("List comprehension exemplos")
print(f"\nHistórico de pesquisas: {historico_pesquisas}")
# 5. Processamento de dados em lote
dados_temperatura = [22.5, 23.1, 23.8, 22.9, 23.5, 24.1]
media = sum(dados_temperatura) / len(dados_temperatura)
print(f"\nTemperatura média: {media:.2f}°C")
# 6. Representação de estruturas de dados mais complexas
# Exemplo: Lista de dicionários (comum em dados JSON)
usuarios = [
{"id": 1, "nome": "Ana", "email": "ana@exemplo.com"},
{"id": 2, "nome": "Bruno", "email": "bruno@exemplo.com"},
{"id": 3, "nome": "Carlos", "email": "carlos@exemplo.com"}
]
print("\nLista de usuários:")
for usuario in usuarios:
print(f" ID: {usuario['id']}, Nome: {usuario['nome']}, Email:
{usuario['email']}")
# 7. Matriz (lista de listas)
matriz = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print("\nMatriz:")
for linha in matriz:
print(f" {linha}")
10. Listas vs. Outros Tipos de Dados
# Comparação entre listas e tuplas
lista_exemplo = [1, 2, 3]
tupla_exemplo = (1, 2, 3)
print("Listas vs. Tuplas:")
print(f" Lista: {lista_exemplo}, Tipo: {type(lista_exemplo)}")
print(f" Tupla: {tupla_exemplo}, Tipo: {type(tupla_exemplo)}")
# Tentativa de modificação
lista_exemplo[0] = 10 # Funciona
print(f" Lista após modificação: {lista_exemplo}")
# tupla_exemplo[0] = 10 # Erro: 'tuple' object does not
support item assignment
print(" Tuplas não podem ser modificadas após a criação")
# Comparação entre listas e conjuntos (sets)
lista_com_duplicados = [1, 2, 2, 3, 3, 3, 4]
conjunto = set(lista_com_duplicados)
print("\nListas vs. Conjuntos (Sets):")
print(f" Lista com duplicados: {lista_com_duplicados}")
print(f" Conjunto (sem duplicados): {conjunto}")
print(" Conjuntos não mantêm ordem e não permitem duplicados")
# Comparação entre listas e dicionários
lista_pares = ["chave1", "valor1", "chave2", "valor2"]
dicionario = {"chave1": "valor1", "chave2": "valor2"}
print("\nListas vs. Dicionários:")
print(f" Lista de pares: {lista_pares}")
print(f" Dicionário: {dicionario}")
print(" Dicionários permitem acesso por chave em vez de índice")
print(f" Acesso por chave: dicionario['chave1'] =
{dicionario['chave1']}")
# Considerações de desempenho
import time
# Teste de desempenho: busca em lista vs. conjunto
tamanho = 10000
lista_grande = list(range(tamanho))
conjunto_grande = set(lista_grande)
elemento_busca = tamanho - 1 # Último elemento (pior caso para lista)
print("\nDesempenho de busca:")
# Busca em lista
inicio = time.time()
resultado_lista = elemento_busca in lista_grande
fim = time.time()
tempo_lista = (fim - inicio) * 1000 # Convertendo para milissegundos
# Busca em conjunto
inicio = time.time()
resultado_conjunto = elemento_busca in conjunto_grande
fim = time.time()
tempo_conjunto = (fim - inicio) * 1000 # Convertendo para
milissegundos
print(f" Tempo de busca em lista: {tempo_lista:.4f} ms")
print(f" Tempo de busca em conjunto: {tempo_conjunto:.4f} ms")
print(f" Conjuntos são geralmente mais rápidos para operações de
busca")
11. Vantagens e Desvantagens das Listas
Vantagens:
5. **Flexibilidade**: As listas podem armazenar qualquer tipo de
dados e podem ser modificadas.
6. **Mutabilidade**: Elementos podem ser adicionados, removidos ou
alterados conforme necessário.
7. **Ordenação**: A ordem dos elementos é preservada e pode ser
alterada.
8. **Métodos incorporados**: Python oferece muitos métodos úteis
para manipular listas.
9. **Indexação e slicing**: Acesso fácil a elementos individuais ou
sublistas.
Desvantagens:
10. **Consumo de memória**: Listas podem consumir mais
memória que outras estruturas de dados.
11. **Desempenho em certas operações**: Operações como
inserção ou remoção no início da lista são O(n).
12. **Não podem ser usadas como chaves de dicionário**:
Por serem mutáveis, não são hasheáveis.
12. Exemplos Práticos e Pequenos Exercícios
Exemplo 1: Sistema de Gestão de Tarefas
# Sistema simples de gestão de tarefas
tarefas = []
def adicionar_tarefa(descricao, prioridade="Normal"):
tarefa = {"descricao": descricao, "prioridade": prioridade, "concluida":
False}
tarefas.append(tarefa)
print(f"Tarefa '{descricao}' adicionada com sucesso!")
def listar_tarefas():
if not tarefas:
print("Não há tarefas registadas.")
return
print("\nLista de Tarefas:")
for i, tarefa in enumerate(tarefas, 1):
status = "✓" if tarefa["concluida"] else " "
print(f"{i}. [{status}] {tarefa['descricao']} (Prioridade:
{tarefa['prioridade']})")
def marcar_concluida(indice):
if 1 <= indice <= len(tarefas):
tarefas[indice-1]["concluida"] = True
print(f"Tarefa '{tarefas[indice-1]['descricao']}' marcada como
concluída!")
else:
print("Índice de tarefa inválido!")
# Demonstração do sistema
adicionar_tarefa("Estudar Python", "Alta")
adicionar_tarefa("Fazer compras")
adicionar_tarefa("Preparar apresentação", "Alta")
listar_tarefas()
marcar_concluida(1)
listar_tarefas()
Exemplo 2: Análise de Dados Simples
# Análise de dados de temperatura
temperaturas = [
{"cidade": "Lisboa", "valores": [12, 14, 15, 16, 15, 13, 14]},
{"cidade": "Porto", "valores": [10, 12, 13, 14, 13, 11, 12]},
{"cidade": "Faro", "valores": [16, 18, 19, 20, 19, 17, 18]}
]
def analisar_temperaturas(dados):
for cidade_dados in dados:
cidade = cidade_dados["cidade"]
temps = cidade_dados["valores"]
media = sum(temps) / len(temps)
minima = min(temps)
maxima = max(temps)
print(f"\nAnálise para {cidade}:")
print(f" Temperatura média: {media:.1f}°C")
print(f" Temperatura mínima: {minima}°C")
print(f" Temperatura máxima: {maxima}°C")
# Usando list comprehension para dias acima da média
dias_acima_media = [i+1 for i, t in enumerate(temps) if t > media]
print(f" Dias acima da média: {dias_acima_media}")
# Executar análise
analisar_temperaturas(temperaturas)
Exercícios:
13. Crie uma função que receba uma lista de números e retorne uma
nova lista contendo apenas os números pares.
14. Implemente uma função que receba duas listas e retorne uma
nova lista contendo os elementos que estão presentes em ambas
(interseção).
15. Crie uma função que simule um baralho de cartas, permitindo
embaralhar e distribuir cartas.
16. Implemente um sistema de notas escolares que calcule a média,
encontre a maior e menor nota, e determine quais alunos foram
aprovados (média >= 10).
17. Crie uma função que receba uma lista de strings e retorne a string
mais longa. Se houver empate, retorne a primeira encontrada.
13. Conclusão
As listas são uma das estruturas de dados mais versáteis e amplamente
utilizadas em Python. Sua mutabilidade e flexibilidade as tornam
adequadas para uma ampla gama de aplicações, desde simples coleções
de itens até estruturas de dados mais complexas.
Nesta aula, exploramos:
Como criar e manipular listas
Métodos e funções para trabalhar com listas
Compreensão de listas como uma forma elegante de criar e
transformar listas
Casos de uso comuns e comparações com outros tipos de dados
Exemplos práticos e exercícios para consolidar o aprendizado
Ao dominar as listas, você terá uma ferramenta poderosa para resolver
muitos problemas de programação. Lembre-se de considerar as
vantagens e desvantagens das listas em relação a outras estruturas de
dados ao projetar suas soluções.
14. Próximos Passos
Para continuar seu aprendizado sobre estruturas de dados em Python,
considere explorar:
Dicionários para mapeamentos chave-valor
Conjuntos (sets) para coleções de elementos únicos
Filas e pilhas para estruturas de dados mais especializadas
Bibliotecas como NumPy para arrays multidimensionais de alto
desempenho
Pandas para análise de dados com DataFrames